1
votes

I have an XSL variable matchedNodes which holds XML data. Which means

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

will produce an XML like this

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

I want to sort this XML so that searfchpage nodes always comes first..Is there any way to do this?

2
try mine and see if its the one you wanted.Hash
@HashCoder I have updated my question a little bit for clarification. As i am not an expert in XSLT i am facing some problems in using your question ,like I am unable to decide where to input my XSL variable matchedNodes in your code.None

2 Answers

3
votes

Simple ordering (move <searfchpage> to the top, keep the rest of the children in orignal order):

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

complex ordering (lets you define any arbitrary order, either dynamically via a param or statically via a hard-coded string):

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

Try this,

Input:

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

Output

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