【问题标题】:XSLT: Sort by multiple itemsXSLT:按多个项目排序
【发布时间】:2011-06-11 07:11:09
【问题描述】:

我有 XML 数据,例如:

<feed>
  <entry>
    <id>4</id>
    <updated>2011-01-18T16:55:54Z</updated>
    <title>title2</title>
  </entry>
  <entry>
    <id>3</id>
    <updated>2011-01-18T16:55:54Z</updated>
    <title>title1</title>
  </entry>
  <entry>
    <id>2</id>
    <updated>2011-01-18T16:55:54Z</updated>
    <title>title1</title>
  </entry>
  <entry>
    <id>1</id>
    <updated>2011-01-18T16:55:54Z</updated>
    <title>title</title>
  </entry>
</feed>

我需要这样的结果:

<feed>
  <entry>
    <id>1</id>
    <updated>2011-01-18T16:55:54Z</updated>
    <title>title</title>
  </entry>
  <entry>
    <id>2</id>
    <updated>2011-01-18T16:55:54Z</updated>
    <title>title1</title>
  </entry>
  <entry>
    <id>3</id>
    <updated>2011-01-18T16:55:54Z</updated>
    <title>title1</title>
  </entry>
  <entry>
    <id>4</id>
    <updated>2011-01-18T16:55:54Z</updated>
    <title>title2</title>
  </entry>
</feed>

基本上我需要 XSLT 对标题进行排序,然后是 ID。我制作了 XSLT,但最后出现的时间较短(使用 Xerces):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:atom="http://www.w3.org/2005/Atom"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />

 <xsl:template match="@* | node()">
  <xsl:copy>
   <xsl:apply-templates select="@* | node()" />
  </xsl:copy>
 </xsl:template>

 <xsl:template match="atom:feed">
  <xsl:copy>
   <xsl:apply-templates select="*" />
   <xsl:for-each select="atom:entry">
    <xsl:sort select="string-length(atom:title)" order="descending" />
    <xsl:sort select="atom:title" data-type="text" order="ascending" />
    <xsl:copy-of select="."/>
   </xsl:for-each>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="atom:feed/atom:entry"/>

</xsl:stylesheet>

【问题讨论】:

  • 如果“较短的项目”是指 entry/title 和较小的 string-length(),则按此长度排序的要求与按字母顺序按 entry/title 排序的要求相冲突。例如,您想如何对标题为“Zoo”和“Alphabet”的两个条目进行排序?其中哪一个应该先出现?请更正您的问题并删除任何相互矛盾的要求。

标签: xslt xerces


【解决方案1】:

对于您的输入示例(实际上不是 Atom 提要),此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="feed">
        <xsl:copy>
            <xsl:apply-templates>
                <xsl:sort select="update" order="descending"/>
                <xsl:sort select="title"/>
                <xsl:sort select="id" data-type="number"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输出:

<feed>
    <entry>
        <id>1</id>
        <updated>2011-01-18T16:55:54Z</updated>
        <title>title</title>
    </entry>
    <entry>
        <id>2</id>
        <updated>2011-01-18T16:55:54Z</updated>
        <title>title1</title>
    </entry>
    <entry>
        <id>3</id>
        <updated>2011-01-18T16:55:54Z</updated>
        <title>title1</title>
    </entry>
    <entry>
        <id>4</id>
        <updated>2011-01-18T16:55:54Z</updated>
        <title>title2</title>
    </entry>
</feed>

注意:只要没有不同的时区,这种日期时间格式可以像字符串一样排序(默认)。

【讨论】:

    猜你喜欢
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-25
    • 1970-01-01
    相关资源
    最近更新 更多