使用XSLT排序

时间:2011-01-13 20:03:52

标签: xml xslt sorting xslt-1.0

更新 - 底部的新代码

我正在试图弄清楚如何使用sort函数从某些XML数据中提取最新记录。我是使用XSLT的新手,遇到了很多问题。这是我的数据的一个例子......

<content date="1/13/2011 1:21:00 PM">
    <collection vo="promotion">
        <data vo="promotion" promotionid="64526" code="101P031" startdate="1/7/2011 12:00:00 AM"/>
        <data vo="promotion" promotionid="64646" code="101P046" startdate="1/9/2011 12:00:00 AM"/>
    </collection>
</content>

我想要做的是按降序顺序按升级顺序对数据进行排序,然后只通过HTML输出最大的升级。以下是我正在尝试的内容

更新 - 这是仍然遇到问题的最新版代码。

<html><body>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"  encoding="UTF-8" />
    <xsl:template match="content/collection/data">
        <xsl:apply-templates>
            <xsl:sort select="promotionid" order="descending" data-type="number" />
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="content/collection">
        <xsl:value-of select="data/@promotionid" />
    </xsl:template> 
</xsl:stylesheet>
</body></html>

虽然这确实会返回结果,但我得到的是'64526'而不是'64646'。

有人可以帮忙吗?我也在网上看过你可以按多个字段排序的例子。现在可能值得注意,而不是后来问,我们可能想要通过startdate而不是promotionid来排序。我已经设法提出代码来打破YYYY,MM和DD的日期,但不知道我怎么会开始使用它除了使用那些作为我的选择参数,但我不知道这是否真的有效。

Year
<xsl:value-of select="substring(substring-after(substring-after(data/@startdate,'/'),'/'),1,4)" />

Month
<xsl:value-of select="substring-before(data/@startdate,'/')" />

Day
<xsl:value-of select="substring-before(substring-after(data/@startdate,'/'),'/')" />

提前感谢,我道歉我的新手XSLT技能不足。

-------------------------------------------- ----------

在此处获得一些帮助后,代码已更改,但仍未按预期工作。这是代码......

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"  encoding="UTF-8" />
    <xsl:template match="content/collection/">
            <xsl:apply-templates>
                <xsl:sort select="@promotionid" order="descending" data-type="number" />
            </xsl:apply-templates>
        </xsl:template>

 <xsl:template match="content/collection/data">
        <xsl:if test="position()=1">
                   <xsl:value-of select="@promotionid"/>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

我仍然看到较低的价值而不是更大的价值。也许还有另一种方法可以通过排序来做到这一点?我也对这种可能性持开放态度。

1/14/11 10:37更新 * ---------------------------------------------- --------------------- * 好吧,现在使用此代码确实对数据进行排序并输出最高的promotionid数。谢谢你!

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="collection">
      <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select="data">
         <xsl:sort select="@promotionid" data-type="number" order="descending"/>
        </xsl:apply-templates>
      </xsl:copy>
    </xsl:template>
<xsl:template match="content/collection/data">
        <xsl:if test="position()=1">
                   <xsl:value-of select="@promotionid"/>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

现在忽略promtionid你能告诉我如何按日期排序,降序吗?我尝试删除不幸的是我知道日期应该有一个静态长度,但我们无法控制我们收到的数据: - (

你也可以推荐一本书,以便真正能够更好地理解这一切吗?你得到了很大的帮助!

1 个答案:

答案 0 :(得分:5)

<xsl:sort select="promotionid" order="descending" data-type="number"
     

/&GT;

这里有一个明显的错误promotionid是一个属性,而不是一个元素。

<强>解决方案

select="@promotionid" order="descending" data-type="number" />

另一个错误

<xsl:template match="content/collection/data">
    <xsl:apply-templates>
        <xsl:sort select="promotionid" order="descending" data-type="number" />
    </xsl:apply-templates>
</xsl:template>

<xsl:apply-templates>并且排序太晚了。

你想要

<xsl:template match="content/collection/">
            <xsl:apply-templates>
                <xsl:sort select="@promotionid" order="descending" data-type="number" />
            </xsl:apply-templates>
        </xsl:template>

    <xsl:template match="content/collection/data">
        <xsl:if test="position()=1">
                   <xsl:value-of select="@promotionid"/>
        </xsl:if>
    </xsl:template>

至于您的扩展问题

这种转变:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="collection">
      <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select="data">
         <xsl:sort select="@promotionid" data-type="number" order="descending"/>
         <xsl:sort select=
          "concat(
             substring-after(substring-after(substring-before(@startdate,' ')
                                             ,'/'
                                             ),
                               '/'
                               ),
             substring-before(substring-after(substring-before(@startdate,' ')
                                             ,'/'
                                             ),
                              '/'
                            ),
             substring-before(substring-after(substring-before(@startdate,' ')
                                             ,'/'
                                             ),
                               '/'
                               )
                )"/>
        </xsl:apply-templates>
      </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<content date="1/13/2011 1:21:00 PM">
    <collection vo="promotion">
        <data vo="promotion" promotionid="64526" code="101P031" startdate="1/7/2011 12:00:00 AM"/>
        <data vo="promotion" promotionid="64646" code="101P046" startdate="1/9/2011 12:00:00 AM"/>
    </collection>
</content>

产生想要的结果

<content date="1/13/2011 1:21:00 PM">

   <collection vo="promotion">
      <data vo="promotion" promotionid="64646" code="101P046" startdate="1/9/2011 12:00:00 AM"/>
      <data vo="promotion" promotionid="64526" code="101P031" startdate="1/7/2011 12:00:00 AM"/>
   </collection>

</content>

但是,请注意,这不能处理日期组件的可变长度。最好使用固定长度格式:mm / dd / yyyy