使用XSLT查找节点和特定属性值

时间:2013-05-06 20:42:54

标签: xslt xpath

这是我的xml代码的一个例子:

<db>
  <group>
  <name>Team1</name>
    <set num="1">AAA</set>
    <set num="2">BBB</set>
    <set num="3">CCC</set>
  </group>
  <group>
  <name>Team2</name>
    <set num="1">DDD</set>
    <set num="2">AAA</set>
    <set num="3">FFF</set>
    <set num="4">EEE</set>
  </group>
  <group>
  <name>Team3</name>
    <set num="1">AAA</set>
    <set num="2">GGG</set>
    <set num="3">FFF</set>
  </group>
  <group>
  <name>Team4</name>
    <set num="1">BBB</set>
    <set num="2">EEE</set>
    <set num="3">AAA</set>
  </group>
</db>

我如何使用xslt显示AAA的num小于3的所有实例的名称和数字,所以我的输出看起来像这样:

<result value="AAA">
  <name num="1">Team1</name>
  <name num="2">Team2</name>
  <name num="1">Team3</name>
</result>

我一直试图使用的代码如下:

...
<xsl:template match="/db">
  <result value="AAA">
    <xsl:for-each select="group[set/@num &lt; '3' and set='AAA']">
      <name num="{@num}">
        <xsl:value-of select="name" />
      </name>
    </xsl:for-each>
  </result>
</xsl:template>

但这给了我所有包含“AAA”而不管num的组,并且无论如何,num总是显示为“”。

任何帮助都会受到赞赏,因为我是XSLT的新手。 谢谢!

1 个答案:

答案 0 :(得分:1)

这应该这样做:

  <xsl:template match="/db">
    <result value="AAA">
      <xsl:for-each select="group[set[@num &lt; 3 and string(.)='AAA']]">
        <name num="{set[@num &lt; 3 and string(.)='AAA']/@num}">
          <xsl:value-of select="name" />
        </name>
      </xsl:for-each>
    </result>
  </xsl:template>

问题是set/@num &lt; '3' and set='AAA'分别测试@numset,而需要的是同时匹配两个条件的set元素 - 这样做嵌套限制[set[@num &lt; 3 and string(.)='AAA']] =所有具有set子元素且@num小于3且包含AAA的子组。

重复相同的测试以从正确的@num子元素中获取set的值。

避免重复测试的替代方法:

  <xsl:template match="/db">
    <result value="AAA">
      <xsl:for-each select="group">
        <xsl:variable name="theSet" select="set[@num &lt; 3 and string(.)='AAA']"/>
        <xsl:if test="$theSet">
          <name num="{$theSet/@num}">
            <xsl:value-of select="name" />
          </name>
        </xsl:if>
      </xsl:for-each>
    </result>
  </xsl:template>