XSLT: How to flatten a structure to XML using XSLT 1
Question
I am trying to flatten a hierarchy / structure to XML using XSLT 1 but not having success. - even finding good links...
input xml
<Address addressType="R">
<Structured xmlns="cds_dt">
<Line1>15 Paradise</Line1>
<City>Toronto</City>
<CountrySubdivisionCode>-50</CountrySubdivisionCode>
<PostalZipCode>
<PostalCode>A1A1O1</PostalCode>
</PostalZipCode>
</Structured>
</Address>
desired output xml
<Address addressType="R">
<Formatted xmlns="cds_dt">15 Paradise, Toronto, A1A1O1</Formatted>
</Address>
I tried this .xsl but no luck - error in file
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="cds">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[ancestor::address]">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()[ancestor::address::Structured]">
<xsl:value-of select="concat(',',.)"/>
</xsl:template>
</xsl:stylesheet>
Solution
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="cds_dt">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="x:Structured">
<xsl:element name="Formatted" namespace="cds_dt">
<xsl:value-of select=
"concat(x:Line1, ', ', x:City, ', ', x:PostalZipCode/x:PostalCode)"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<Address addressType="R">
<Structured xmlns="cds_dt">
<Line1>15 Paradise</Line1>
<City>Toronto</City>
<CountrySubdivisionCode>-50</CountrySubdivisionCode>
<PostalZipCode>
<PostalCode>A1A1O1</PostalCode>
</PostalZipCode>
</Structured>
</Address>
produces the wanted, correct result:
<Address addressType="R">
<Formatted xmlns="cds_dt">15 Paradise, Toronto, A1A1O1</Formatted>
</Address>
Explanation: Overriding of the identity rule + proper use of namespaces and the <xsl:element>
instruction.
OTHER TIPS
Do you mean something like that:
<Address addressType="R">
<Formatted xmlns="cds_dt">
<xsl:value-of select="concat(Line1, ', ', City, PostalZipCode/PostalCode )"/>
</Formatted>
</Address>
Note: I have shortened the paths of the arguments to concat() for readability. So instead of Line1
, it should actually be Address/Structured/Line1
.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow