Reputation: 275
<?xml version="1.0"?>
<parent id="38" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<child id="1" colorType="firstColor" colorKey="blue"/>
<child id="2" colorType="secondColor" colorKey="red"/>
</parent>
So I have the previous XML and I would like to transform it, using XSLT, in the following way:
<?xml version="1.0"?>
<parent id="38" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
firstColor="blue" secondColor="red">
</parent>
So two values from the child element to be used as a pair attribute in the parent, removing the child element in the process. I tried but can't wrap my head around what seems to be the basics of XSLT.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="parent">
<parent>
<xsl:apply-templates/>
</parent>
</xsl:template>
<xsl:template match="parent">
<parent>
<xsl:attribute name="{@colorType}">
<xsl:value-of select="@colorKey"/>
</xsl:attribute>
</parent>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 1970
Reputation: 57189
I would go for something like the following, i.e., simply applying templates to child
and matching it, so that each child will turn into attributes:
<xsl:template match="parent">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="child" />
</xsl:copy>
</xsl:template>
<xsl:template match="child">
<xsl:attribute name="{@colorType}" select="@colorKey" />
</xsl:template>
I generally prefer applying templates to for-each'ing over a set of nodes, as it is usually easier to adapt later, and is (generally) easier to follow.
Upvotes: 1
Reputation: 70648
You are on the right lines, but you actually need to create an attribute for each child
element under parent
, so you could use xsl:for-each
here:
Try replacing your parent
template with this:
<xsl:template match="parent">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each select="child">
<xsl:attribute name="{@colorType}">
<xsl:value-of select="@colorKey" />
</xsl:attribute>
</xsl:for-each>
</xsl:copy>
</xsl:template>
Also note the use of xsl:copy-of
to copy the existing attributes. Also note the use of <xsl:copy>
instead of just doing <parent>
as this will ensure the namespace declaration for "xsi" is copied too.
Upvotes: 3