0

i need some help with sorting xmlelements based on another xml. my main xml is as below

<xml>
<A1>value</A1>
<A2>value</A2>
<B1>value</B1>
<B2>value</B2>
</xml>

i want another xml which looks liks this

<xml>
<A1>value</A1>
<B1>value</B1>
<A2>value</A2>
<B2>value</B2>
</xml>

sortign is not based on any key or any value. the ordering is determined on the fly(by reading the order from DB) and the main xml has to be transposed to that order. from db values are like

tagname | order
------------
A1 | 1
B1 | 2
A2 | 3
A3 | 4

how do i do this? i can form the xslt dynamically. but what should that xslt be?

Thanks in advance.

3
  • I don't understand your question. If the sort order is "not based on any key or any value" then what is it based on? XSLT can read from the source XML or from other documents you point it at (in XSLT 1.0, these too would be have to be XML documents). It cannot "read from DB". Commented Oct 28, 2015 at 18:53
  • it is not based on any key. we have predefined list of elements and the ordering of elements are determined dynamically. so it is better that order information comes from DB. i can read db values and form a xslt by writing a c# program. Commented Oct 29, 2015 at 18:43
  • Do you mean you create the XSLT itself "on-the-fly"? If yes, can you insert this table into in the form of XML - for example: <elem name="A1" order="1"/>? Commented Oct 29, 2015 at 18:49

1 Answer 1

1

How about ...

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

<xsl:variable name="elem-order" as="element(elem)*">
  <elem name="A1" />
  <elem name="B1" />
  <elem name="A2" />
  <elem name="B2" />
</xsl:variable>

<xsl:template match="/*">
  <xsl:copy>
    <xsl:apply-templates select="@*|comment()|processing-instruction()|text()" />
    <xsl:apply-templates select="*">
      <xsl:sort select="index-of( $elem-order, $elem-order[@name eq local-name( current())])" data-type="number" />
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

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

</xsl:transform>

If the element order is to come from an external file, redefine the $elem-order variable like so ...

<xsl:variable
    name="elem-order"
    select="doc('what-ever-uri')/elements/elem" />

... or pass it in as a stylesheet parameter.

Sign up to request clarification or add additional context in comments.

3 Comments

can you give me the main xml that will work with this xsl? when i try my main example, it is giving error
I don't understand. What is a main xml? And what was the error message?
Thanks Sean. How should this xml be? <xml> <A1>value</A1> <A2>value</A2> <B1>value</B1> <B2>value</B2> </xml>

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.