使用具有相对平坦的分层树结构的导入JSON数据。在当前代码中,我将在元素创建过程中应用属性集。
是否可以先创建所有元素,然后再应用属性集?“use- attribute -set”似乎是一个属性,因此需要添加到元素中才能工作。
在我的当前代码中没有错误消息。
我只是想看看是否有可能按照一定的顺序做一些事情,如下所述。此计划更改的原因是处理更大的数据量,从而首先执行元素的解析和创建,只有在这一步之后,才执行通过属性集添加属性的统一方法。
我的顺序是:
[1] Create attribute sets.
[2] Group element names.
[3] Parse JSON to XML map.
[4] Build element, using attribute-sets and extract key value我想要表演的顺序:
[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:
<data>
{
"store": {
"pencils": 43,
"milk": 21,
"rulers": 12,
"beer": 17
}
}
</data>XSL:
<?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>结果(当前及其在代码序列更改后的外观):
<?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>发布于 2021-05-27 18:46:12
这是一种相当人工的分离,并不是很容易分离,因为您不能在不创建元素的情况下注入属性集,因此,如果这样做有帮助,那么编写一个具有高优先级的模板来选择元素名称并将其传递给一个期望该名称作为参数的较低级别的模板,然后像以前一样,执行真正的工作来创建具有属性集的元素:
<!-- [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对临时树的基于模式的建议也是一种选择,但需要临时树;或者您可以使用上面的方法,而不是依赖优先级来确保处理顺序,使用一种模式并推动同一节点通过,对我来说,这就像以前那样人为的、困难的分离:
<!-- [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>发布于 2021-05-27 15:40:52
您可以使用这样的模式(添加了一些元素以使想要的阶段变得清晰):
<?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>这将给出这样的结果:
<?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阶段,您还可以这样保存它:
<xsl:result-document href="stage-4.xml">
<inventory:store>
<xsl:copy-of select="$withoutAttributeSets"/>
</inventory:store>
</xsl:result-document>https://stackoverflow.com/questions/67724842
复制相似问题