首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对现有元素应用属性集

对现有元素应用属性集
EN

Stack Overflow用户
提问于 2021-05-27 14:59:55
回答 2查看 67关注 0票数 1

使用具有相对平坦的分层树结构的导入JSON数据。在当前代码中,我将在元素创建过程中应用属性集。

是否可以先创建所有元素,然后再应用属性集?“use- attribute -set”似乎是一个属性,因此需要添加到元素中才能工作。

在我的当前代码中没有错误消息。

我只是想看看是否有可能按照一定的顺序做一些事情,如下所述。此计划更改的原因是处理更大的数据量,从而首先执行元素的解析和创建,只有在这一步之后,才执行通过属性集添加属性的统一方法。

我的顺序是:

代码语言:javascript
复制
[1] Create attribute sets. 
[2] Group element names. 
[3] Parse JSON to XML map. 
[4] Build element, using attribute-sets and extract key value

我想要表演的顺序:

代码语言:javascript
复制
[1] Create attribute sets (same as above).
[2] Group element names (same as above).
[3] Parse JSON to XML map (same as above).
[4] Build element names with corresponding key (split of above bullet 4).
[5] Add attribute-set based on template match in the code (split of above bullet 4).

JSON:

代码语言:javascript
复制
<data>
{
  "store": {
    "pencils": 43,
    "milk": 21,
    "rulers": 12,
    "beer": 17
  }
}
</data>

XSL:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>

<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:inventory="http://www.example.org/1"
  xmlns:item="http://www.example.org/2"
  expand-text="yes"
>

  <xsl:output method="xml" indent="yes"/>
  <xsl:mode on-no-match="shallow-skip"/>

  <!-- [1] Create attribute sets -->

  <xsl:attribute-set name="group-office">
    <xsl:attribute name="contextRef">office</xsl:attribute>
  </xsl:attribute-set>

  <!-- [2] Group element names-->

  <xsl:param name="group-office">pencils, rulers</xsl:param>
  <xsl:param name="attributes-for-group-office" select="tokenize($group-office, ',\s*')"/>

  <!-- [3] Parse JSON to XML -->

  <xsl:template match="data">
      <inventory:store>
        <xsl:apply-templates select="json-to-xml(.)/*"/>
      </inventory:store>
  </xsl:template>

  <!-- [4] Build element, using attribute-sets and extract key value -->

  <xsl:template match="*[@key = 'store']/*[@key = $attributes-for-group-office]">
    <xsl:for-each select=".">
      <xsl:element name="item:{@key}" use-attribute-sets="group-office">
        <xsl:value-of select="text()"/>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>

</xsl:transform>

结果(当前及其在代码序列更改后的外观):

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<inventory:store xmlns:inventory="http://www.example.org/1"
                 xmlns:item="http://www.example.org/2">
   <item:pencils contextRef="office">43</item:pencils>
   <item:rulers contextRef="office">12</item:rulers>
</inventory:store>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-27 18:46:12

这是一种相当人工的分离,并不是很容易分离,因为您不能在不创建元素的情况下注入属性集,因此,如果这样做有帮助,那么编写一个具有高优先级的模板来选择元素名称并将其传递给一个期望该名称作为参数的较低级别的模板,然后像以前一样,执行真正的工作来创建具有属性集的元素:

代码语言:javascript
复制
  <!-- [4] Extract key value for element name -->

  <xsl:template match="*[@key = 'store']/*[@key = $attributes-for-group-office]" priority="10">
    <xsl:next-match>
      <xsl:with-param name="element-name" select="'item:' || @key"/>
    </xsl:next-match>
  </xsl:template>
  
  <!-- [5] Build element and add attribute-set based on template match in the code -->

  <xsl:template match="*[@key = 'store']/*[@key = $attributes-for-group-office]" priority="5">
    <xsl:param name="element-name" required="yes"/>
    <xsl:element name="{$element-name}" use-attribute-sets="group-office">
      <xsl:value-of select="text()"/>
    </xsl:element>
  </xsl:template>

我不确定分离是否有任何意义,但就目前而言,如果您真的需要两个单独的模板,我就想不出任何其他的东西了。当然,Siebe对临时树的基于模式的建议也是一种选择,但需要临时树;或者您可以使用上面的方法,而不是依赖优先级来确保处理顺序,使用一种模式并推动同一节点通过,对我来说,这就像以前那样人为的、困难的分离:

代码语言:javascript
复制
  <!-- [4] Build element and extract key value -->

  <xsl:template match="*[@key = 'store']/*[@key = $attributes-for-group-office]">
    <xsl:apply-templates select="." mode="add-attribute-sets">
      <xsl:with-param name="element-name" select="'item:' || @key"/>
    </xsl:apply-templates>
  </xsl:template>
  
  <!-- [5] Build element and add attribute-set based on template match in the code -->

  <xsl:template match="*[@key = 'store']/*[@key = $attributes-for-group-office]" mode="add-attribute-sets">
    <xsl:param name="element-name" required="yes"/>
    <xsl:element name="{$element-name}" use-attribute-sets="group-office">
      <xsl:value-of select="text()"/>
    </xsl:element>
  </xsl:template>
票数 3
EN

Stack Overflow用户

发布于 2021-05-27 15:40:52

您可以使用这样的模式(添加了一些元素以使想要的阶段变得清晰):

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>

<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:inventory="http://www.example.org/1"
  xmlns:item="http://www.example.org/2"
  expand-text="yes"
  >
  
  <xsl:output method="xml" indent="yes"/>
  <xsl:mode on-no-match="shallow-skip"/>
  <xsl:mode name="useAttributeSet" on-no-match="shallow-skip"/>
  
  <!-- [1] Create attribute sets -->
  
  <xsl:attribute-set name="group-office">
    <xsl:attribute name="contextRef">office</xsl:attribute>
  </xsl:attribute-set>
  
  <!-- [2] Group element names-->
  
  <xsl:param name="group-office">pencils, rulers</xsl:param>
  <xsl:param name="attributes-for-group-office" select="tokenize($group-office, ',\s*')"/>
  
  <!-- [3] Parse JSON to XML -->
  
  <xsl:template match="data">
    <xsl:variable name="withoutAttributeSets">
      <xsl:apply-templates select="json-to-xml(.)/*"/>
    </xsl:variable>
    <stages>
      <stage>
        <inventory:store>
          <xsl:copy-of select="$withoutAttributeSets"/>
        </inventory:store>
      </stage>
      <stage>
        <inventory:store>
          <xsl:apply-templates select="$withoutAttributeSets" mode="useAttributeSet"/>
        </inventory:store>
      </stage>
    </stages>
  </xsl:template>
  
  <!-- [4] Build element names with corresponding key (split of above bullet 4). -->
  
  <xsl:template match="*[@key = 'store']/*[@key = $attributes-for-group-office]">
    <xsl:for-each select=".">
      <xsl:element name="item:{@key}" >
        <xsl:value-of select="text()"/>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>
  
  <!-- [5] Add attribute-set based on template match in the code (split of above bullet 4). -->

  <xsl:template match="*[local-name() = $attributes-for-group-office]" mode="useAttributeSet">
  <xsl:element name="{name()}" use-attribute-sets="group-office">
      <xsl:value-of select="text()"/>
    </xsl:element>
  </xsl:template>

</xsl:transform>

这将给出这样的结果:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<stages xmlns:inventory="http://www.example.org/1"
        xmlns:item="http://www.example.org/2">
   <stage>
      <inventory:store>
         <item:pencils>43</item:pencils>
         <item:rulers>12</item:rulers>
      </inventory:store>
   </stage>
   <stage>
      <inventory:store>
         <item:pencils contextRef="office">43</item:pencils>
         <item:rulers contextRef="office">12</item:rulers>
      </inventory:store>
   </stage>
</stages>

根据你的需要调整它。

如果您想以其他方式重用这个4阶段,您还可以这样保存它:

代码语言:javascript
复制
<xsl:result-document href="stage-4.xml">
  <inventory:store>
    <xsl:copy-of select="$withoutAttributeSets"/>
  </inventory:store>
</xsl:result-document>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67724842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档