我正在进行转型。目标是将节点转换为键/值对。在这个论坛上找到一个很棒的样式表推荐,但我可以用一些帮助来调整一下。对于没有子节点的任何节点,节点名称应该变为<name>
的值,并且该值应该成为<value>
的值。源文档可能有一些层次结构,但我想忽略它,只返回底部节点,当然转换。
这是我的源数据:
<?xml version="1.0" encoding="UTF-8"?>
<objects>
<Technical_Spec__c>
<Id>a0e30000000vFmbAAE</Id>
<F247__c>4.0</F247__c>
<F248__c xsi:nil="true"/>
<F273__c>Bronx</F273__c>
...
</Technical_Spec__c>
</objects>
这是样式表:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*[count(*) = 0]">
<item>
<name>
<xsl:value-of select="name(.)" />
</name>
<value>
<xsl:value-of select="." />
</value>
</item>
</xsl:template>
<xsl:template match="*[count(*) > 0]">
<items>
<xsl:apply-templates/>
</items>
</xsl:template>
</xsl:stylesheet>
期望的输出 - 样式表应该将这些节点转换为键值对,如下所示:
<items>
<item>
<name>F247__c</name>
<value>4.0</value>
</item>
<item>
<name>F248__c</name>
<value></value>
</item>
<item>
<name>F273__c</name>
<value>Bronx</value>
</item>
...
</items>
CURRENT OUTPUT - 但它会创建嵌套的“items”元素,如下所示:
<items>
<items>
<item><name></name><value></value></item>
...
</items>
</items>
我理解(我认为)它匹配所有父节点,包括顶级节点'对象'并嵌套'匹配计数0'模板。所以我尝试改变匹配属性以排除'对象'并从'Technical_Spec__c'开始,就像这样(只是模板行):
<xsl:template match="objects/Technical_Spec__c/*">
<xsl:template match="*[count(*) = 0]">
<xsl:template match="objects/*[count(*) > 0]">
在我看来,这说“First(master)模板只匹配带有父对象/ Tech_Spec的节点。”Second(内部)模板匹配任何没有子节点的节点。第三(外部)模板匹配具有父'对象'的节点 - 这应该限制我一个。
改变比赛后的输出 - 这是我得到的:
<?xml version="1.0" encoding="UTF-8"?>
- <items xmlns=""><?xml version="1.0"?>
<item><name>Id</name><value>a0e30000000vFmbAAE</value></item>
<item><name>F247__c</name><value>4.0</value></item>
...
</items>
额外的<items>
块已经消失,但中间有一个额外的<?xml>
块,所以它不再被识别为有效的xml。
有什么想法吗?为什么额外<?xml>
;如何将模板限制为树的特定部分?
答案 0 :(得分:0)
通过大量的反复试验,我偶然发现了以下解决方案:我在第三个模板匹配条件中添加了一个根锚点。
而不是match="*[count(*) > 0]"
,我现在有/*[count(*) > 0]
。这似乎消除了外部<items>
元素。如果有人能告诉我原因,我会很感激。为什么这会与/objects/*[count(*) > 0]
不同?
我确实认为Dimitre对处理器(IBM Cast Iron)是对的,所以我确实打开了一张票。我在在线XSLT测试器上测试了相同的样式表,但没有得到额外的<?xml ?>
标签。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*[count(*) = 0]">
<item>
<name>
<xsl:value-of select="name(.)" />
</name>
<value>
<xsl:value-of select="." />
</value>
</item>
</xsl:template>
<xsl:template match="/*[count(*) > 0]">
<items>
<xsl:apply-templates/>
</items>