XSL不同的子节点

时间:2011-12-06 23:04:35

标签: xml xslt

我有和xml

<Top>
    <Node1>
        <Class1>
            <Test name="test1"></Test>
            <Test name="test2"></Test>
        </Class1>
    </Node1>
    <Node2>
        <Class1>
            <Test name="test1"></Test>
            <Test name="test2"></Test>
        </Class1>
    </Node2>
</Top>

期望的结果:

test1 - Node1&amp;&amp;节点2

test2 - Node1&amp;&amp;节点2

我尝试使用Distinct,但我做错了。

有人可以帮我解决这个问题。

谢谢, 吉里什

1 个答案:

答案 0 :(得分:1)

<强>予。这是一个简单的XSLT 1.0解决方案,使用Muenchian grouping method

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kTestByName" match="Test"
          use="@name"/>

 <xsl:template match=
  "Test
     [generate-id()
     =
      generate-id(key('kTestByName', @name)[1])
     ]
  ">
  <xsl:value-of select=
  "concat(@name, ' -- ')"/>

  <xsl:apply-templates mode="group"
      select="key('kTestByName', @name)"/>
  <xsl:text>&#xA;</xsl:text>
 </xsl:template>

 <xsl:template match="Test" mode="group">
  <xsl:if test="position() > 1"> &amp;&amp; </xsl:if>
  <xsl:value-of select="name(../..)"/>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于提供的XML文档

<Top>
    <Node1>
        <Class1>
            <Test name="test1"></Test>
            <Test name="test2"></Test>
        </Class1>
    </Node1>
    <Node2>
        <Class1>
            <Test name="test1"></Test>
            <Test name="test2"></Test>
        </Class1>
    </Node2>
</Top>

产生了想要的正确结果

test1 -- Node1 && Node2
test2 -- Node1 && Node2

<强> II。使用 <xsl:for-each-group> 以及 current-group() current-grouping-key() 功能的XSLT 2.0解决方案:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output method="text"/>

 <xsl:template match="/*">
  <xsl:for-each-group select="*/*/Test"
                      group-by="@name">
   <xsl:value-of select=
   "concat(current-grouping-key(), ' -- ')"/>

   <xsl:apply-templates select="current-group()"/>
   <xsl:text>&#xA;</xsl:text>
  </xsl:for-each-group>
 </xsl:template>

 <xsl:template match="Test">
  <xsl:if test="position() > 1"> &amp;&amp; </xsl:if>
  <xsl:value-of select="name(../..)"/>
 </xsl:template>
</xsl:stylesheet>

当在同一个XML文档(上面)上应用此XSLT 2.0转换时,会生成相同的想要和正确的结果

test1 -- Node1 && Node2
test2 -- Node1 && Node2