很抱歉,我的标题不太清楚:我很难想出一种正确表达问题的正确方法。
这是我的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
:列出他们的孩子(这里我只介绍name
),还列出所有book
当前id
与writers
中的至少一个匹配的地方。如果未找到book
匹配项,则不应显示该特定book
的{{1}}列表。对于所有匹配项,该列表应按价格降序排序。
以下是到目前为止我已经完成的代码的重要author
部分:
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
。我似乎无法理解如何确保只验证要迭代的 current "//book[//author/@id = @writers]"
的ID的匹配项。另外,由于author
可以有多个book
(writers
到IDREFS
的ID),所以我不确定如何应用author
运算符。 / p>
结果将是这样的:
contains
答案 0 :(得分:1)
假设您仅限使用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>
适用于您的示例,结果为:
<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>
呈现为: