XSLT:如何循环使用多个子节点作为关键字段的每个唯一节点?

时间:2013-05-27 09:45:46

标签: xslt foreach

<A>
    <B>
        <C>
            <Name>John</Name>
            <Age>21</Name>
            <Sex>Male</Name>
        </C>
        <C>
            <Name>John</Name>
            <Age>50</Name>
            <Sex>Male</Name>
        </C>
        <C>
            <Name>John</Name>
            <Age>21</Name>
            <Sex>Male</Name>
        </C>
    </B>
</A>

我只想知道如何循环每个唯一节点“C”。如果节点“C”具有不同的“名称”,“年龄”和“性别”子节点,则它是唯一的。

我希望根据上面的示例循环到2“C”节点。

3 个答案:

答案 0 :(得分:2)

这是你要找的吗?

<xsl:template match="A/B">
   <xsl:for-each select="C">
       <xsl:if test="not(following-sibling::C[Name = current()/Name and Age = current()/Age and Sex = current()/Sex])">
          <xsl:value-of select="Name" />, <xsl:value-of select="Age" />
       </xsl:if>
   </xsl:for-each>
</xsl:template>

这将输出前2个C节点的名称,年龄。

答案 1 :(得分:2)

这是一个分组问题。使用xslt-1.0的“正常”解决方案是 muenchian分组(例如,查看this)。

因此,为您的分组条件添加一个xslt键:

<xsl:key name="kUniqueC" match="C"  use="concat(Name,'|', Age, '|', Sex)"/>

循环群组:

<xsl:for-each select="//C[
             generate-id() = generate-id(key('kUniqueC', concat(Name,'|', Age, '|', Sex))[1])
              ]" >

试试这个:

         

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="/">
    <xsl:for-each select="//C[
         generate-id() = generate-id(key('kUniqueC', concat(Name,'|', Age, '|', Sex))[1])
          ]" >
        <xsl:apply-templates select="." />
    </xsl:for-each>
</xsl:template>

输出:

<C>
  <Name>John</Name>
  <Age>21</Age>
  <Sex>Male</Sex>
</C><C>
  <Name>John</Name>
  <Age>50</Age>
  <Sex>Male</Sex>
</C>

答案 2 :(得分:0)

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<div>
  <xsl:for-each select="A/B/C">
    <xsl:variable name="name" select="Name"/>
    <xsl:variable name="age" select="Age"/>
    <xsl:variable name="sex" select="Sex"/>

    <xsl:variable name="numEntries" select="count(//C[Name=$name][Age=$age][Sex=$sex])"/>
<xsl:variable name="i" select="position()" />

<xsl:choose>
 <xsl:when test="$numEntries=1">
       <p><xsl:value-of select="Name" /></p>
       <p><xsl:value-of select="Age" /></p>
       <p><xsl:value-of select="Sex" /></p>
</xsl:when>
<xsl:when test="$i &gt; $numEntries">
       <p><xsl:value-of select="Name" /></p>
       <p><xsl:value-of select="Age" /></p>
       <p><xsl:value-of select="Sex" /></p>
</xsl:when>
 </xsl:choose>
  </xsl:for-each>
</div>
</xsl:template>

</xsl:stylesheet>