tony
tony

Reputation: 277

One single XSLT template to transform one XML into another which follows a slightly different XSD?

I am new to the idea/knowledge of XSLT. I've seen it used minimally to transform XML data into HTML to visualize on web pages.

I need some help just understanding the approach of how to use XSLT for a particular scenario. For example I have two separate XSDs that are quite similar and two separate XML files, one that validates to one XSD and the other that validates to the other.

So if I'm giving one of the XML files and I need to transform it so that it validates to the different XSD what is the best practical approach for this?

I'm not looking for code but rather trying to see how XSLT is used for these situations. And yes I've seen examples of this from other questions posted. Usually I see that some template is used that transforms an XML file into the needed format which may follow a different XSD. So I guess my question is, does one create a single large XSLT template that follows the entire structure of the target XSD file?

So accounting for every kind of element present in the XSD (simple and complex) with nested loops and so forth. Let's assume the XSDs have a common structure (around 85% same). If so, what happens to elements in an XML file that are not accounted for in the XSLT template? Are they excluded?

Or is there alternative ways to do this maybe not using XSLT. I've just heard so many people talk about XSLT for these kinds of tasks, I'm curious now.

Upvotes: 0

Views: 704

Answers (1)

kjhughes
kjhughes

Reputation: 111621

If the XSDs governing the input and output XML documents are substantially similar, common practice is to use an identity transformation that will, by default, copy nodes exactly from input to output.

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

For those nodes that should not be identical, special templates are written to generate the differences. If <abc/> should be mapped to <xyz/>, then

  <xsl:template match="abc">
    <xyz/>
  </xsl:template>

merely has to be added to the identity transformation, and the 1:1 mapping will be modified specifically for abc elements to be mapped differently.


Update to address question in comments

For the following input XML,

<parent>
  <child>
    <child_child></child_child>
  </child>
</parent>

Yes, this template

  <xsl:template match="parent"/>

would prevent parent and all of its descendants from being copied to the output by the identity transform template.

Michael.hor257k already answered this for you in the comments. Attend to the part of his answer that stated that an empty template does not contain a recursive xsl:apply call. (Understand why the identity transformation template recursively calls xsl:apply and notice that an empty template such as the one shown above for parent does not.)

Upvotes: 1

Related Questions