5

我正在使用 XSLT 从提要中获取数据。目前我使用这个代码块,它只是从提要中挑选出第一个项目。我对其进行了一些更改,因此它适用于此示例 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”。

4

3 回答 3

3

我想按价格对 xml 进行排序,然后选择与价格最高的书关联的作者。

FWIW,您也可以使用纯 XPath 来做到这一点。

/catalog/book[not(price < /catalog/book/price)]/author

(谓词为:“选择任何不低于任何书的书。” <book><price>

这将<author>Galos, Mike</author>示例 XML中选择。

笔记

  • 这个表达式不选择价格最高书,而是选择所有价格最高的书(即,如果有两本书的价格相同,它将选择两本书)。采用

    /catalog/book[not(price < /catalog/book/price)][1]/author
    

    准确选择一本匹配的书(将选择文档顺序中的第一个)。

  • XPath 自动将“小于/大于(或等于)”类型的比较类型的两个操作数强制为numbers。只要 的值<price>可以直接转换为数字,上面的表达式就会成功。

  • 它必须是逆逻辑(“不(低于任何)”),因为相反的(“大于任何”)永远不会为真(而“大于或等于任何”总是为真)。

  • 操作的时间复杂度nodeset1[expression < nodeset2]为:
    O(count(nodeset1) × count(nodeset2))
    在上述情况下nodeset1nodeset2相同,因此有效时间复杂度为:
    O(n²)
    换句话说,它不是解决这个问题的最有效方法(我会说<xsl:apply-templates><xsl:sort>),但另一方面 - 它是一个单线,可能对你来说足够快。

于 2012-11-06T14:39:15.037 回答
1

您可以指定一个<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>

然后在你的小“书”模板中,使用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>
于 2012-11-06T13:58:40.457 回答
0

您需要并使用 position 函数只返回第一个:

<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>
于 2012-11-06T14:08:03.367 回答