1

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. Commented Nov 7, 2013 at 8:48
  • @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. Commented Nov 7, 2013 at 8:55

2 Answers 2

3

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>
Sign up to request clarification or add additional context in comments.

6 Comments

I don't completely get the first one itself..The XML i showed above is in an xsl variable..can you please tell me how i could pass this variable to this function?
What do you mean by "The XML is in an <xsl:variable>"? Is it a string? A result tree fragment? A node set? -- It's best if you add to your question the bit of code that sets the variable.
Yeah, that's a result tree fragment. You can't easily sort that. I think there is enough indication that your entire approach might be wrong. You can try <xsl:apply-templates select="$matchedNodes"/> instead of the <xsl:copy-of>, but it's impossible to say without knowing what $matchedNodes actually contains.
$matchedNodes contains the XML i had shown in my question..that's it..Am i missing anything?
As I said, without seeing the input XML and the workflow you apply to it I'm forced to guess. My best guess is the apply-templates suggestion in the comment above. To give you a definitive answer I would need to see more of your code. If possible, cut it down to the simplest example that correctly demonstrates your situation.
|
1

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.