将 for-each 中的元素 ID 与另一个元素的 ID 匹配

Match an element's ID from within a for-each with another element's ID

抱歉,如果我的标题不是很清楚:我很难想出一个正确的方式来简洁地表达我的问题。

这是我的 XML 结构的样子:

<library>
    <books>
        <book writers="007,911">
            <title>Two authors wrote me</title>
            <price>4.00</price>
        </book>
        <book writers="911">
            <title>Only one here</title>
            <price>2.50</price>
        </book>
    </books>
    <authors>
        <author id="007">
            <name>James</name>
        </author>
        <author id="911">
            <name>Police</name>
        </author>
        <author id="666">
            <name>Diablo</name>
        </author>
    </authors>
</library>

我的目标,对于每一个author:列出他们的children(这里我只呈现name),而且要列出当前 id 至少匹配 writers 之一的所有 book。如果未找到 book 匹配项,则不应显示该特定 authorbook 列表。该列表应按所有匹配项的价格降序排列。

这是我目前完成的基本 XSLT 部分代码:

<xsl:template match="/"> <!-- I'm skipping all the irrelevant <html> stuff, of course. -->

    <body>
        <ol> 
            <xsl:for-each select="//author">
                <li>
                    <b>ID: </b><xsl:value-of select="@id"/>
                    <ul>
                        <xsl:call-template name="auth_infos"></xsl:call-template>
                        <xsl:call-template name="books_stuff"></xsl:call-template>
                    </ul>
                </li>
            </xsl:for-each>
        </ol>
    </body>

</xsl:template>

<xsl:template name="auth_infos">
    <li><b>Name: </b><xsl:value-of select="name"/></li>
</xsl:template>

<xsl:template name="books_stuff">
    <xsl:if test="//book[//author/@id = @writers]"> <!-- This is supposed to make sure that if the author doesn't have any books listed in the database, then there shouldn't be an empty list of books. Only his name should be presented. -->
        <li><b>Book(s): </b>
            <xsl:for-each select="//book[//author/@id = @writers]">
                <xsl:sort select="price" order="descending"/> <!-- Because I would also like to sort them based on their price. -->
                <li><b>Title: </b><xsl:value-of select="//title"/></li>
            </xsl:for-each>
        </li>
    </xsl:if>
</xsl:template>

显然我在处理这个特定的 XPath 表达式: "//book[//author/@id = @writers]" 时遇到了麻烦。我似乎无法理解如何确保只验证正在迭代的 current author 的 id 的匹配。此外,由于 book 可以有多个 writersIDREFSauthor 的 ID),我不确定如何应用 contains 运算符。

结果会是这样的:

-ID: 007
    -Name: James
    -Book(s):
        -Title: Two authors wrote me
-ID: 911
    -Name: Police
    -Book(s):
        -Title: Two authors wrote me
        -Title: Only one here
-ID: 666
    -Name: Diablo

假设您仅限于 XSLT 1.0,这会有点尴尬:

XSLT 1.0

<xsl:stylesheet version="1.0"   
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    
<xsl:output method="html" encoding="utf-8"/>  

<xsl:template match="/library">    
   <body>
        <ol> 
            <xsl:for-each select="authors/author">
                <xsl:variable name="books" select="../../books/book[contains(concat(',', @writers, ','), concat(',', current()/@id, ','))]"/>
                <li>
                    <b>ID: </b>
                    <xsl:value-of select="@id"/>
                    <ul>
                        <li>
                            <b>Name: </b>
                            <xsl:value-of select="name"/>
                        </li>
                        <xsl:if test="$books">
                            <li>
                                <b>Book(s): </b>
                                <ul>
                                    <xsl:for-each select="$books">
                                        <xsl:sort select="price" data-type="number" order="descending"/> 
                                        <li><b>Title: </b><xsl:value-of select="title"/></li>
                                    </xsl:for-each>
                                </ul>
                            </li>
                        </xsl:if>
                    </ul>
                </li>
            </xsl:for-each>
        </ol>
    </body>
</xsl:template>    

</xsl:stylesheet>    

应用于你的例子,结果s:

<body><ol>
<li>
<b>ID: </b>007<ul>
<li>
<b>Name: </b>James</li>
<li>
<b>Book(s): </b><ul><li>
<b>Title: </b>Two authors wrote me</li></ul>
</li>
</ul>
</li>
<li>
<b>ID: </b>911<ul>
<li>
<b>Name: </b>Police</li>
<li>
<b>Book(s): </b><ul>
<li>
<b>Title: </b>Two authors wrote me</li>
<li>
<b>Title: </b>Only one here</li>
</ul>
</li>
</ul>
</li>
<li>
<b>ID: </b>666<ul><li>
<b>Name: </b>Diablo</li></ul>
</li>
</ol></body>

呈现为: