I have a sample xml file which looks like this:
--- before transformation ---
<root-node>
<child-type-A> ... </child-type-A>
<child-type-A> ... </child-type-A>
<child-type-B> ... </child-type-B>
<child-type-C>
<child-type-B> ... </child-type-B>
...
</child-type-C>
...
</root-node>
I want to transform this xml file into something that looks like that:
--- after transformation ---
<root-node>
<child-node> ... </child-node>
<child-node> ... </child-node>
<child-node> ... </child-node>
<child-node>
<child-node> ... </child-node>
...
</child-node>
...
</root-node>
Effectively that means that the document structure remains the same, but some 'chosen' elements are renamed. These chosen elements start with the same prefix (in this example with "child-type-") but have varying suffixes ("A" | "B" | "C" | etc.).
Why all this hassle? I have a software that demands an xml file as input. For sake of convenience I use an XML schema to easily edit an xml file and the schema helps making sure the xml file will be correct. Sadly XML schemas are lacking somewhat when it comes to aspects of context sensitivity. This leads to the xml file looking like shown in /before transformation/. The software cannot process such an xml file because it expects a file as shown in /after transformation/. Thus the need for the transformation.
I want to do the transformation with XSLT and I already figured out how to do so. My approach was to define a rule for an identity transformation and one rule for each "child-type-*" element which needs to be renamed. This solution works but it isn't that elegant though. You end up with lots of rules.
--- sample transformation rules ---
<!-- Identity transformation -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="child-type-A">
<xsl:element name="child-node">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
...
Is there a way to condense that into only two rules? One for the identity transformation and one for all "child-type-*" elements? Maybe by using XSLT in combination with some regular expression? Or do you have to take a different approach to tackle such a problem?