2012-11-06 22 views
4

我正在使用XSLT从Feed中获取数据。目前我使用这个block of code,它只是从饲料中挑选出第一个项目。我改变了一点,所以它适用于这个示例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”。

回答

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> 
+0

正是我在找的东西。我的第二个问题是如何过滤排序列表中的第二项,但也回答了。谢谢! –

+0

不客气! –

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> 
+0

感谢您指出“position()= first()”。 –

+0

'position()= first()'相当于'position()= 1',只有更长的时间。 – Tomalak

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>的值可以直接转换为数字,上述表达式就会成功。

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

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

相关问题