sequence in transformation using xslt

廉价感情. 提交于 2019-12-13 06:47:34

问题


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>

回答1:


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>


来源:https://stackoverflow.com/questions/23343204/sequence-in-transformation-using-xslt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!