Reputation: 5448
I have this following xslt. I notice that sometimes the element name 'tuple' has an attribute. I want to remove the attribute and add it as an Element. I added a test to verify if 'tuple' has an attribute but it returns a blank 'ecatalogue' element.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="atom">
<xsl:element name="{@name}">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="table">
<xsl:element name="{@name}">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<!--this test doesn't work properly -->
<xsl:template match="tuple">
<xsl:choose>
<xsl:when test="@name">
<xsl:apply-templates />
</xsl:when>
<xsl:otherwise>
<!-- nothing to do
the node should stay the same
-->
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- end test -->
</xsl:stylesheet>
result I had with this template above.
<ecatalogue>
</ecatalogue>
https://gist.github.com/guinslym/5ce47460a31fe4c4046b
Upvotes: 2
Views: 4866
Reputation: 116959
I notice that sometimes the element name 'tuple' has an attribute. I want to remove the attribute and add it as an Element. I added a test to verify if 'tuple' has an attribute
This is definitely not the best approach when working with XSLT. You want to transform the attribute, not its parent tuple
element - so your template should match the attribute directly, for example:
<xsl:template match="tuple/@*">
<xsl:element name="{name()}">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
No tests are required here: if the attribute exists, the template will match it and process it; if not, the template will not be applied at all.
--
Note: the above is assuming you want to transform the attribute into a child element of tuple
, sibling to the other, already existing, children.Your post is not quite clear on that point.
Upvotes: 4
Reputation: 11416
With the following adjustments to your template matching tuple
<xsl:template match="tuple">
<xsl:choose>
<xsl:when test="@name">
<tuple>
<xsl:element name="{@name}"/>
<xsl:apply-templates />
</tuple>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
all tuple
nodes without a name
attribute are copied:
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:otherwise>
and in case a tuple
has a name
attribute, the tuple
is written without an attribute, the attribute added as element (without any value as it's not clear if it should have any value) and the child nodes copied:
<xsl:when test="@name">
<tuple>
<xsl:element name="{@name}"/>
<xsl:apply-templates />
</tuple>
</xsl:when>
Part of the input XML as example:
<tuple name="ObjManufacturerRef">
<NamOrganisation>Unknown;:;Inconnu</NamOrganisation>
<NamOrganisationAcronym>Unknown</NamOrganisationAcronym>
<AddPhysCountry>Unknown</AddPhysCountry>
</tuple>
results in:
<tuple>
<ObjManufacturerRef/>
<NamOrganisation>Unknown;:;Inconnu</NamOrganisation>
<NamOrganisationAcronym>Unknown</NamOrganisationAcronym>
<AddPhysCountry>Unknown</AddPhysCountry>
</tuple>
Saved example: http://xsltransform.net/nc4NzQq/1 with an added <xsl:strip-space elements="*"/>
to remove whitespace.
Upvotes: 2