Background
A more general version of my problem was recently posted but due to the quality of the post, it received no responses. Here's my attempt!
I have the following XML structure that I want to transform
Pre-processed XML
<schema>
<!-- element to be imbedded -->
<element name="tryCatch.catch">
<complexType>
<complexContent>
<extension base="escalateContainer">
<attribute name="var" type="_var" />
</extension>
</complexContent>
</complexType>
</element>
<complexType name="tryCatch">
<complexContent>
<extension base="scriptElement">
<sequence>
<element name="try" type="escalateContainer" />
<element name="catch" type="tryCatch.catch" minOccurs="0" />
<element name="finally" type="escalateContainer" minOccurs="0" />
</sequence>
</extension>
</complexContent>
</complexType>
</schema>
...into the following structure:
Post XSLT-Structure
<schema>
<complexType name="tryCatch">
<complexContent>
<extension base="scriptElement">
<sequence>
<element name="try" type="escalateContainer" />
<!-- Change here! -->
<element name="tryCatch.catch" minOccurs="0">
<complexType>
<complexContent>
<extension base="escalateContainer">
<attribute name="var" type="_var" />
</extension>
</complexContent>
</complexType>
</element>
<element name="finally" type="escalateContainer" minOccurs="0" />
</sequence>
</extension>
</complexContent>
</complexType>
</schema>
Overview of the Process
Basically, I just want to
- Copy everything
Then find all
element
children of acomplexType
that have a.
in their type (by construction - I have ensured this pattern works interally in my XML). A simplified version of my match is:complexType.element.type = element.name
Last, replace that element with the corresponding global element. Bonus points if the attributes on the element being replaced are also copied.
What I have So Far
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="schema">
<xsl:for-each select="element">
<xsl:variable name="self" select="current()" />
<xsl:variable name="name" select="@name" />
<xsl:for-each select="/schema/complexType//element[@type=$name]">
<xsl:copy-of select="$self" />
</xsl:for-each>
</xsl:for-each>
</xsl:template>
I think I'm off to the right start - copy everything with the identity template, then process what I want to change. The problem is that my second template only returns the copied element! The match appears to work great, I just lose all the other content I'm trying to preserve.