如何限制哪些节点在样式表中生成输出

时间:2011-09-23 20:59:49

标签: templates xslt match

我正在进行转型。目标是将节点转换为键/值对。在这个论坛上找到一个很棒的样式表推荐,但我可以用一些帮助来调整一下。对于没有子节点的任何节点,节点名称应该变为<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>;如何将模板限制为树的特定部分?

1 个答案:

答案 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>