Reputation: 1626
I have XML like this:
<Parent>
<Elem1 Attr1="1" Attr2="2">
<Elem2>
<Elem3 Attr1="4" Attr2="5"></Elem3>
</Elem2>
</Elem1>
</Parent>
and it should be turned into this:
<Parent>
<Elem1 Attr1="1+2">
<Elem2>
<Elem3 Attr1="4+5"></Elem3>
</Elem2>
</Elem1>
</Parent>
The problem is that I don't know the names of the elements, that is, Elem1
or Elem3
in this case. I know is that elements must contain both the attribute Attr1
and the attribute Attr2
but not all such element names ahead of time.
I also know that parent element must have the name Parent
, but children containing the attributes may be at any level, either immediate descendants or deeper in the parent tree.
The closest to the possible solution that I could find is this StackOverflow post but my XSLT knowledge is not good enough to try to adapt it to this case.
Upvotes: 0
Views: 1305
Reputation: 116993
I think you want to do something like:
XSLT 1.0
<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:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@Attr1[../@Attr2]">
<xsl:attribute name="Attr1">
<xsl:value-of select="."/>
<xsl:text>+</xsl:text>
<xsl:value-of select="../@Attr2"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@Attr2[../@Attr1]"/>
</xsl:stylesheet>
Upvotes: 1
Reputation: 167561
One way to solve that is
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Parent//*[@Attr1 and @Attr2]/@Attr1">
<xsl:attribute name="Attr1" select="concat(., '+', ../@Attr2)"/>
</xsl:template>
<xsl:template match="Parent//*[@Attr1 and @Attr2]/@Attr2"/>
</xsl:transform>
http://xsltransform.net/ejivdHM
Upvotes: 1