I have an XML file with the following structure.
<Telefon>
<area>0123</area>
<number>456</number>
<extension>789</extension>
</Telefon>
<Fax>
<area>3210</area>
<number>654</number>
<extension>1098</extension>
</Fax>
I would like to transform this using XSLT to the following
<telefon-area>0123</area>
<telefon-number>456</number>
<telefon-extension>789</extension>
<fax-area>3210</area>
<fax-number>654</number>
<fax-extension>1098</extension>
I got so far as using the copy template, and while I could write templates to manually change these fields, I would like to only writes one adding the telefon- or fax- prefix to each child nodes of the previous Telefon and Fax nodes.
This is the structure I come up with so far:
<!-- The copy template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--The next template removes the telefon tag but I do not know how to modify the child nodes to extend them with the telefon- prefix.-->
<xsl:template match="Telefon">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
Thank you for your help!
To match the children of the Telefon
node, you could do this...
<xsl:template match="Telefon/*">
And you could extend it like this, to handle Fax
too
<xsl:template match="Telefon/*|Fax/*">
Within this, you could use xsl:element
together with local-name()
to create a new element name.
Try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<!-- The copy template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--The next template removes the telefon tag but I do not know how to modify the child nodes to extend them with the telefon- prefix.-->
<xsl:template match="Telefon|Fax">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="Telefon/*|Fax/*">
<xsl:element name="{local-name(..)}-{local-name()}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Note, in the template matching Telefon
, you only really need do <xsl:apply-templates />
as you probably want to ignore any attributes on Telefon
if there were any.
Alternatively, you could make use of a "mode", if you had other elements, in addition to Telefon
and Fax
you wanted to change too
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<!-- The copy template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--The next template removes the telefon tag but I do not know how to modify the child nodes to extend them with the telefon- prefix.-->
<xsl:template match="Telefon|Fax">
<xsl:apply-templates mode="child" />
</xsl:template>
<xsl:template match="*" mode="child">
<xsl:element name="{local-name(..)}-{local-name()}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Note, this doesn't make the name all lower-case. If you wanted that, then it would depend if you were using XSLT 2.0 or XSLT 1.0.
Ideally, you can use XSLT 2.0, and do this...
<xsl:element name="{lower-case(local-name(..))}-{local-name()}">
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.