6

更新 - 底部的新代码

我试图弄清楚如何使用排序功能从一些 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>

我想做的是按promotionid按降序对数据进行排序,然后仅通过HTML输出最大的promotionid。这是我正在尝试的内容

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

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

而且我仍然看到较小的价值输出而不是较大的输出。也许还有另一种方法可以做到这一点而不进行排序?因为我也对这种可能性持开放态度。

2011 年 1 月 14 日 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,您能告诉我如何按日期降序排序吗?我尝试删除不幸的是我知道日期应该有一个静态长度,但我们无法控制我们收到的数据:-(

您也可以推荐一本书以真正可以更好地理解这一切吗?你帮了大忙!

4

1 回答 1

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

/>

这里有一个明显的错误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

于 2011-01-13T20:37:01.847 回答