首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用xslt选择节点的第一个匹配项

如何使用xslt选择节点的第一个匹配项
EN

Stack Overflow用户
提问于 2013-03-28 22:51:29
回答 3查看 8.8K关注 0票数 5

我有一个xml,它类似于:

代码语言:javascript
复制
<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”节点的所有唯一子节点。

所以输出应该是:

代码语言:javascript
复制
author
title
price

我将xslt编写为:

代码语言:javascript
复制
<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>

它还我,nothing...Could,有人在这方面给我一些帮助吗?谢谢!!

更新:

如果我的xml中有几个“书店”元素,而我只想限制每个“书店”上下文中的唯一性,这样即使“作者”也出现在一个“书店”中,如果它出现在另一个“书店”中,它仍然可以显示呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-28 23:17:18

如果使用XSLT1.0,获取不同元素的方法是使用一种称为Muenchian分组的技术。在您的示例中,您希望按book子元素进行“分组”,因此首先定义一个键来根据元素名称查找图书的子元素。

代码语言:javascript
复制
 <xsl:key name="child" match="book/*" use="local-name()" />

要获得不同的名称,您可以查看所有book子元素,但只输出组中为其给定名称首先出现的元素。你用这个可怕的说法来做这件事:

代码语言:javascript
复制
<xsl:apply-templates 
   select="//book/*[generate-id() = generate-id(key('child', local-name())[1])]" />

以下是完整的XSLT

代码语言:javascript
复制
<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(), '&#10;')" />
   </xsl:template>
</xsl:stylesheet>

当应用于XML时,将输出以下内容

代码语言:javascript
复制
author
title
price
票数 3
EN

Stack Overflow用户

发布于 2013-03-29 02:08:54

略短/简单--完全以“推式”表示:

代码语言:javascript
复制
<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文档时的

代码语言:javascript
复制
<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>

想要的,正确的结果产生:

代码语言:javascript
复制
author
title
price

解释

门窗分组法的适当使用。

票数 3
EN

Stack Overflow用户

发布于 2013-03-28 23:01:40

您可以使用<xsl:for-each select="//book">来选择发生

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15693547

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档