如何使用xslt选择第一次出现的节点

时间:2013-03-28 22:51:29

标签: xslt xpath

我有一个xml,如:

<bookstores>
    <bookstore>
        <book id="1">
            <author>ABC</author> 
        </book>
        <book id="2">
            <title>YYY</title> 
        </book>
    </bookstore>
    <bookstore>
        <book id="3">
            <author>ABC</author> 
        </book>
        <book id="4">
            <author>DEF</author> 
        </book>
    </bookstore>
    <bookstore>
        <book id="5">
            <price>50</price>
        </book>
        <book id="6">
            <title>ZZZ</title> 
        </book>
    </bookstore>
</bookstores>

我想选择第一次出现'book'节点的子节点,换句话说,就是'book'节点的所有唯一子节点。

所以输出应该是:

author
title
price

我写了一个xslt:

<xsl:for-each select="bookstores/bookstore/book"> 
    <xsl:if test="count(preceding-sibling::*[1]) = 0">
        <xsl:value-of select="local-name(*[1])"/>
    </xsl:if>
</xsl:for-each>

它没有给我任何回报......有人能给我一些帮助吗?谢谢!

更新

如果我的xml中有几个'bookstores'元素怎么办?我只想限制每个'bookstores'的上下文中的唯一性,这样即使'author'出现在一个'bookstores'中,它仍然可以如果它出现在另一个'书店'中显示?

2 个答案:

答案 0 :(得分:2)

更短/更简单 - 完全采用“推送式”:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:key name="kBChildrenByName" match="book/*" use="name()"/>

 <xsl:template match=
  "book/*[generate-id()=generate-id(key('kBChildrenByName', name())[1])]">
     <xsl:value-of select="concat(name(), '&#xA;')"/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

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

<bookstores>
    <bookstore>
        <book id="1">
            <author>ABC</author>
        </book>
        <book id="2">
            <title>YYY</title>
        </book>
    </bookstore>
    <bookstore>
        <book id="3">
            <author>ABC</author>
        </book>
        <book id="4">
            <author>DEF</author>
        </book>
    </bookstore>
    <bookstore>
        <book id="5">
            <price>50</price>
        </book>
        <book id="6">
            <title>ZZZ</title>
        </book>
    </bookstore>
</bookstores>

产生了想要的正确结果:

author
title
price

<强>解释

正确使用 Muenchian grouping method

答案 1 :(得分:-1)

你可以使用 <xsl:for-each select="//book">选择出现次数