我正在使用XSLT从Feed中获取数据。目前我使用此block of code,它只是从Feed中选择第一项。我稍微改了一下,所以它适用于这个示例XML。
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="/">
<xsl:value-of select="catalog/book/author"/>
</xsl:template>
</xsl:stylesheet>
我想按价格对xml进行排序,然后选择与价格最高的图书相关联的作者。我尝试过各种各样的东西,但我似乎无法弄明白。
目前的输出是“Gambardella,Matthew”,但我需要它是“Galos,Mike”。
答案 0 :(得分:3)
我想按价格对xml进行排序,然后选择与价格最高的图书相关联的作者。
FWIW,你也可以用纯XPath做到这一点。
/catalog/book[not(price < /catalog/book/price)]/author
(谓词上写着:“选择<book>
不低于任何图书的任何<price>
。”
这会在sample XML中选择<author>Galos, Mike</author>
。
注释
此表达式不会选择 最高价格的书籍,而是所有最高价格的书籍(即,如果有两本书,它会选择两本书同样的价格)。使用
/catalog/book[not(price < /catalog/book/price)][1]/author
选择一本匹配的书(将选择文档顺序中的第一本书)。
XPath会自动强制“少于/大于(或等于)”类型与numbers进行比较的两个操作数。只要<price>
的值可以直接转换为数字,上述表达式就会成功。
它必须是反逻辑(“not(低于任何)”),因为相反的(“大于任何”)永远不会是是的(而“大于或等于任何”总是如此)。
nodeset1[expression < nodeset2]
操作的时间复杂度为:
→ O(count(nodeset1)×count(nodeset2))
在上述情况nodeset1
和nodeset2
相同,因此有效时间复杂度为:
→ O(n²)。
换句话说,它不是解决这个问题的最有效方法(我会说<xsl:apply-templates>
与<xsl:sort>
是),但另一方面 - 它是一个单行,很可能是对你来说足够快。
答案 1 :(得分:1)
您可以在apply-templates中指定<xsl:sort>
,如下所示:
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="/catalog/book">
<xsl:sort select="price" order="descending" data-type="number"/>
</xsl:apply-templates>
</body>
</html>
</xsl:template>
然后在您的小'book'模板中,使用position()
过滤掉第一个图书节点
<xsl:template match="book">
<xsl:if test="position() = 1">
<xsl:value-of select="author"/>
<br/>
<xsl:value-of select="price"/>
</xsl:if>
</xsl:template>
答案 2 :(得分:0)
您需要并使用位置功能仅返回第一个:
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="/catalog/book">
<xsl:sort select="price" order="descending" data-type="number"/>
</xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="book">
<xsl:if test="position()=first()">
<xsl:value-of select="author"/>
</xsl:if>
</xsl:template>