使用XSLT对XML中的节点进行排序

时间:2013-11-07 06:24:58

标签: xml xslt xslt-1.0

我有一个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节点始终排在第一位。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:3)

简单排序(将<searfchpage>移到顶部,让剩下的孩子保持原状顺序):

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

答案 1 :(得分:1)

试试这个,

<强>输入:

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