首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >匹配一个或多个子节点的XSL键

匹配一个或多个子节点的XSL键
EN

Stack Overflow用户
提问于 2019-07-25 21:39:42
回答 1查看 105关注 0票数 0

我有一个由书名构成的复杂XML文件。就像这样,但每本书都有几百本书,有时还有很多作者。

代码语言:javascript
复制
<Book>
    <Title>Ken Lum</Title>
    <Author>
        <GivenName>Grant</GivenName>
        <Surname>Arnold</Surname>
    </Author>
</Book>
<Book>
    <Title>Shore, Forest and Beyond</Title>
    <Author>
        <GivenName>Ian M.</GivenName>
        <Surname>Thom</Surname>
    </Author>
    <Author>
        <GivenName>Grant</GivenName>
        <Surname>Arnold</Surname>
    </Author>
</Book>

我需要输出的是一个按字母顺序排列的作者列表,然后是他们工作过的每一本书的列表,也是字母化的,类似于:

阿诺德,格兰特-朗姆;海岸,森林和更远 Thom,Ian M. - Shore,Forest和Beyond

我有一个版本的代码运行得相当好,但是它非常慢,所以我正在尝试优化我的方法。最近,我从另一个用户那里了解到分组的Muenchian法,我正在尝试应用这个方法。

我现在特别关注的部分是获得每个作者的标题列表。这就是我现在拥有的:

代码语言:javascript
复制
<xsl:key name="books-by-author" match="Book"
         use="concat(Author/GivenName, Contributor/Surname)" />
…
<xsl:template match="Author">
    …
    <xsl:apply-templates mode="ByAuthor" select=
                                "key('books-by-author',
                                     concat(GivenName, Surname)
                                     )">
        <xsl:sort select="Title/TitleText"/>
    </xsl:apply-templates>
</template>

但是,这似乎只是匹配的书籍,其中作者是第一个列出的,例如:

阿诺德,格兰特-兰姆 Thom,Ian M. - Shore,Forest和Beyond

我认为xsl:key只使用第一个Author元素,而不是检查每个作者。有可能像这样检查每一个Author吗?还是有更好的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-25 22:28:31

我建议你这样看:

XML

代码语言:javascript
复制
<Books>
    <Book>
        <Title>Ken Lum</Title>
        <Author>
            <GivenName>Grant</GivenName>
            <Surname>Arnold</Surname>
        </Author>
    </Book>
    <Book>
        <Title>Shore, Forest and Beyond</Title>
        <Author>
            <GivenName>Ian M.</GivenName>
            <Surname>Thom</Surname>
        </Author>
        <Author>
            <GivenName>Grant</GivenName>
            <Surname>Arnold</Surname>
        </Author>
    </Book>
</Books>

XSLT1.0

代码语言:javascript
复制
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="author" match="Author" use="concat(Surname, ', ', GivenName)" />

<xsl:template match="/Books">   
    <Authors>
        <!-- for each unique author -->
        <xsl:for-each select="Book/Author[count(. | key('author', concat(Surname, ', ', GivenName))[1]) = 1]">
            <xsl:sort select="Surname"/>
            <xsl:sort select="GivenName"/>
            <Author>
                <!-- author's details-->
                <xsl:copy-of select="Surname | GivenName"/>
                <!-- list author's books -->
                <Books>
                    <xsl:for-each select="key('author', concat(Surname, ', ', GivenName))/parent::Book">
                        <xsl:sort select="Title"/>
                        <xsl:copy-of select="Title"/>
                    </xsl:for-each> 
                </Books>
            </Author>
        </xsl:for-each>
    </Authors>
</xsl:template>

</xsl:stylesheet>

结果

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<Authors>
  <Author>
    <GivenName>Grant</GivenName>
    <Surname>Arnold</Surname>
    <Books>
      <Title>Ken Lum</Title>
      <Title>Shore, Forest and Beyond</Title>
    </Books>
  </Author>
  <Author>
    <GivenName>Ian M.</GivenName>
    <Surname>Thom</Surname>
    <Books>
      <Title>Shore, Forest and Beyond</Title>
    </Books>
  </Author>
</Authors>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57210452

复制
相关文章

相似问题

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