Domanda

I am working on xml transformation from XML to XML. I have XSD defined for newly transformed XML. XSD has some predefined sequence/order for each element. How can I make same sequence from XSD will appears while XML transformation?

I tried to arrange transformation sequence as same order as in my XSD but learnt that transformation sequence is not same as xslt execution sequence.

Appreciate your response

<ROOT>
  <A1>A</A1>
  <B1>B</B1>
  <C1>C</C1>
  <D1>D</D1>
</ROOT>

<ROOT>
 <a1>A</a1>
 <d1>D</d1>
 <b1>B</b1>
 <c1>C</c1>
</ROOT>

I tried below based on your suggestion

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="ROOT">
    <xsl:apply-templates select="A1,D1,C1,B1" />
</xsl:template> 

<xsl:template match="A1">
    <a1>
        <xsl:apply-templates />
    </a1>
 </xsl:template>

 <xsl:template match="B1">
    <b1>
        <xsl:apply-templates />
    </b1>
 </xsl:template>

 <xsl:template match="C1">
    <c1>
        <xsl:apply-templates />
    </c1>
</xsl:template>

  <xsl:template match="D1">
    <d1>
        <xsl:apply-templates />
    </d1>
  </xsl:template>

 </xsl:stylesheet>
È stato utile?

Soluzione

XSLT processes your input document and applies your templates so you need to write your XSLT in a way that it produces the proper output. You have not provided any information about the input you have and how it maps to the output you want, only that you have a schema for the output format. While XSLT 2.0 knows schema-aware XSLT processing that mainly means validating input and/or output to a schema or set of schemas, there is no magic to ensure the output is created according to a schema.

So you will have to write your code to ensure you get the result you want, including the order your are looking for respectively the schema defines.

For instance if you have an input

<foo>
  <child1>...</child1>
  <child2>...</child2>
</foo>

and you want to create

<bar>
  <child2>...</child2>
  <child1>...</child1>
</bar>

then you write the template for foo as

<xsl:template match="foo">
  <bar>
    <xsl:apply-templates>
      <xsl:sort select="position()" order="descending"/>
    </xsl:apply-templates>
  </bar>
</xsl:template>

or for instance as

<xsl:template match="foo">
  <bar>
    <xsl:apply-templates select="child2, child1"/>
  </bar>
</xsl:template>

As for the concrete samples you have provided in an edit, you are nearly there, with some improvements

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

<xsl:output indent="yes"/>

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

<xsl:template match="ROOT">
  <ROOT>
    <xsl:apply-templates select="A1,D1,C1,B1" />
  </ROOT>
</xsl:template> 

<xsl:template match="A1">
    <a1>
        <xsl:apply-templates />
    </a1>
 </xsl:template>

 <xsl:template match="B1">
    <b1>
        <xsl:apply-templates />
    </b1>
 </xsl:template>

 <xsl:template match="C1">
    <c1>
        <xsl:apply-templates />
    </c1>
</xsl:template>

  <xsl:template match="D1">
    <d1>
        <xsl:apply-templates />
    </d1>
  </xsl:template>

 </xsl:stylesheet>

and an XSLT 2.0 processor like Saxon 9 I get

<ROOT>
   <a1>A</a1>
   <d1>D</d1>
   <c1>C</c1>
   <b1>B</b1>
</ROOT>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top