【问题标题】:XSLT: Sorting like SOLRXSLT:像 SOLR 一样排序
【发布时间】:2011-01-26 12:06:34
【问题描述】:

我正在使用 XSLT 对一段 XML 进行排序,例如:

<feed>
   <entry>
      <title>A To Z</title>
   </entry>
   <entry>
      <title>Action</title>
   </entry>
</feed>

XSLT 看起来像:

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

 <xsl:param name="name" select="'title'" />
 <xsl:param name="order" select="'ascending'" />

 <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="/atom:feed/*[not(self::atom:entry)]" />
   <xsl:apply-templates select="/atom:feed/atom:entry">
    <xsl:sort select="*[name() = $name]" order="{$order}" />
    <xsl:sort select="atom:id" data-type="number" />
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

我希望这些值按 A 到 Z,然后是 Action 的顺序出现,但结果却相反。看起来空格被忽略为排序依据。

【问题讨论】:

  • @smokedice 我删除了一些未使用的参数和名称空间,以使 XSLT 更易于阅读。如果您认为这些对问题很重要,请发表评论或编辑
  • @smokedice:好像对我有用,怎么失败了?
  • 问题是生成的第一个标题是Action,然后是A到Z。@Lazarus你是用Xerces来应用模板的吗?
  • 我使用了 Altova XMLSpy 中的内置引擎,对我来说效果很好。我认为@Nick Jones 可能已经在下面的回答中指出了这一点。
  • @smokedice:我不会使用name(),除非我确定命名空间是默认命名空间还是绑定到前缀。另外,请注意您的输入文档没有 Atom 命名空间声明。

标签: xml xslt sorting


【解决方案1】:

这个样式表:

<xsl:stylesheet version="1.0"
 xmlns:atom="http://www.w3.org/2005/Atom"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="name" select="'title'" />
    <xsl:param name="order" select="'ascending'" />
    <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="*[not(self::atom:entry)]" />
            <xsl:apply-templates select="atom:entry">
                <xsl:sort select="*[local-name() = $name]" order="{$order}" />
                <xsl:sort select="atom:id" data-type="number" />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

使用此输入(带有命名空间声明):

<feed xmlns="http://www.w3.org/2005/Atom">
    <entry>
        <title>A To Z</title>
    </entry>
    <entry>
        <title>Action</title>
    </entry>
</feed>

输出:

<feed xmlns="http://www.w3.org/2005/Atom">
    <entry>
        <title>A To Z</title>
    </entry>
    <entry>
        <title>Action</title>
    </entry>
</feed>

使用 MSXSL 3/4、Saxon、Altova、XQSharp 进行测试。 注意:只有 Oracle、和 Xalan 按升序将“Action”排在“A To Z”之前。

【讨论】:

  • 嗨亚历杭德罗。使用 xslt 时,Xerces 以错误的顺序输出数据: pastebin.com/aefethTq pastebin.com/WQkmCSVg 。有什么想法吗?
【解决方案2】:

在 XSLT 1.0 中,排序是由实现定义的,因此很可能某些实现忽略了用于排序的空间。您使用的是哪种实现方式?

我会推荐类似的东西:

<xsl:sort select="translate(*[name() = $name],' ','_')" order="{$order}" />

可能会解决您的问题(尽管再次取决于您使用排序“_”的 XSLT 实现方式)

【讨论】:

  • 我无法真正将 _ 添加到数据中。一旦对 XML 进行排序,然后将其与原始数据进行比较以查看数据是否已排序。
  • 这不会将_添加到数据中,只会添加到为数据排序而生成的排序键中。
猜你喜欢
  • 1970-01-01
  • 2015-12-16
  • 2020-01-16
  • 1970-01-01
  • 2015-04-26
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多