我有一个 xml,如下所示:
\n\n<bookstores>\n <bookstore>\n <book id="1">\n <author>ABC</author> \n </book>\n <book id="2">\n <title>YYY</title> \n </book>\n </bookstore>\n <bookstore>\n <book id="3">\n <author>ABC</author> \n </book>\n <book id="4">\n <author>DEF</author> \n </book>\n </bookstore>\n <bookstore>\n <book id="5">\n <price>50</price>\n </book>\n <book id="6">\n <title>ZZZ</title> \n </book>\n </bookstore>\n</bookstores>\nRun Code Online (Sandbox Code Playgroud)\n\n我想选择“book”节点的子节点的第一次出现,或者换句话说,选择“book”节点的所有唯一子节点。
\n\n所以输出应该是这样的:
\n\nauthor\ntitle\nprice\nRun Code Online (Sandbox Code Playgroud)\n\n我写了一个xslt:
\n\n<xsl:for-each select="bookstores/bookstore/book"> \n <xsl:if test="count(preceding-sibling::*[1]) = 0">\n <xsl:value-of select="local-name(*[1])"/>\n </xsl:if>\n</xsl\xef\xbc\x9afor-each>\nRun Code Online (Sandbox Code Playgroud)\n\n它没有给我带来任何回报...任何人都可以给我一些帮助吗?谢谢!!
\n\n更新:
\n\n如果我的 xml 中有多个“bookstores”元素,并且我只想限制每个“bookstores”上下文中的唯一性,以便即使“author”也出现在一个“bookstores”中,该怎么办,如果出现在其他“书店”中还能显示吗?
\n如果您使用的是 XSLT1.0,则获取不同元素的方法是通过称为 Muenchian 分组的技术。在您的情况下,您希望按书籍子元素“分组”,因此首先定义一个键来按元素名称查找书籍的子元素
<xsl:key name="child" match="book/*" use="local-name()" />
Run Code Online (Sandbox Code Playgroud)
为了获得不同的名称,您可以查看所有书籍子元素,但仅输出在给定名称的组中第一个出现的元素。你可以使用这个可怕的语句来做到这一点:
<xsl:apply-templates
select="//book/*[generate-id() = generate-id(key('child', local-name())[1])]" />
Run Code Online (Sandbox Code Playgroud)
这是完整的 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="child" match="book/*" use="local-name()" />
<xsl:template match="/">
<xsl:apply-templates select="//book/*[generate-id() = generate-id(key('child', local-name())[1])]" />
</xsl:template>
<xsl:template match="//book/*">
<xsl:value-of select="concat(local-name(), ' ')" />
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当应用于您的 XML 时,将输出以下内容
author
title
price
Run Code Online (Sandbox Code Playgroud)