【问题标题】:Sort nodes in XML using XSLT使用 XSLT 对 XML 中的节点进行排序
【发布时间】:2013-11-07 16:49:39
【问题描述】:

我有一个 XSL 变量 matchedNodes 保存 XML 数据。这意味着

   <xsl:copy-of select="$matchedNodes"/>

会生成这样的 XML

    <home name="f">
  <standardpage>
    <id text="a1"></id>
  </standardpage>
  <searfchpage>
    <id text="a2"></id>
  </searfchpage>
  <searfchpage>
    <id text="a3"></id>
  </searfchpage>
</home>

我想对这个 XML 进行排序,以便 searfchpage 节点总是排在第一位。有没有办法做到这一点?

【问题讨论】:

  • 试试我的,看看是不是你想要的。
  • @HashCoder 我已经稍微更新了我的问题以便澄清。由于我不是 XSLT 专家,我在使用您的问题时遇到了一些问题,比如我无法决定在您的代码中输入我的 XSL 变量matchedNodes 的位置。

标签: xml xslt xslt-1.0


【解决方案1】:

简单排序(将&lt;searfchpage&gt;移到顶部,其余的孩子保持原始顺序):

<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="home">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:apply-templates select="searfchpage" />
      <xsl:apply-templates select="*[not(self::searfchpage)]" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

复杂排序(让您定义任意顺序,通过参数动态或通过硬编码字符串静态):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:param name="sortOrder" select="'searfchpage,standardpage,otherpage'" />

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

  <xsl:template match="home">
    <xsl:copy>
      <xsl:apply-templates select="@*">
      <xsl:apply-templates select="*">
        <xsl:sort select="string-length(
          substring-before(concat($sortOrder, ',', name()), name())
        )" />
      <xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

【讨论】:

  • 我自己并没有完全得到第一个。我上面显示的 XML 在一个 xsl 变量中。你能告诉我如何将这个变量传递给这个函数吗?
  • “XML 在&lt;xsl:variable&gt;”中是什么意思?它是一个字符串吗?结果树片段?一个节点集? -- 最好在问题中添加设置变量的代码。
  • 是的,这是一个结果树片段。你不能轻易地对它进行排序。我认为有足够的迹象表明您的整个方法可能是错误的。你可以试试&lt;xsl:apply-templates select="$matchedNodes"/&gt;而不是&lt;xsl:copy-of&gt;,但如果不知道$matchedNodes实际包含什么,就不可能说出来。
  • $matchedNodes 包含我在我的问题中显示的 XML..就是这样..我错过了什么吗?
  • 正如我所说,没有看到输入 XML 和应用到它的工作流,我不得不猜测。我最好的猜测是上面评论中的应用模板建议。为了给你一个明确的答案,我需要查看更多你的代码。如果可能的话,把它简化为最简单的例子来正确展示你的情况。
【解决方案2】:

试试这个,

输入:

<home name="f">
  <standardpage>
    <id text="a1"></id>
  </standardpage>
  <searfchpage>
    <id text="a2"></id>
  </searfchpage>
  <searfchpage>
    <id text="a3"></id>
  </searfchpage>
</home>

XSL:

<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>

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

       <xsl:apply-templates select="node()">
        <xsl:sort select="name()"/>
       </xsl:apply-templates>
      </xsl:copy>
     </xsl:template>
    </xsl:stylesheet>

输出

<home name="f">
   <searfchpage>
      <id text="a2"/>
   </searfchpage>
   <searfchpage>
      <id text="a3"/>
   </searfchpage>
   <standardpage>
      <id text="a1"/>
   </standardpage>
</home>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    相关资源
    最近更新 更多