Reputation: 29
I'm getting input request with different namespaces like 'pn', 'tmn','pn2','pn3'..I have to get only elements which have namespaces 'pn2','pn3' and exclude the rest of the elements with other namespaces. How should I write this in XSLT ?
Here is my sample incoming request:
<soap-env:Envelope
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
>
<soap-env:Header/>
<soap-env:Body>
<Details actionCode="04">
<Info>123</Info>
<ID>ABC12</ID>
<pn2:Address
xmlns:pn2="http://www.blah2.com/"
>Address</pn2:Address>
<pn3:City cityID=" " scID=" " ID=" "
xmlns:pn3="http://www.blah3.com/"
>City</pn3:City>
<tmn:City cityID=" " scID=" " ID=" "
xmlns:tmn="http://www.blah.com/"
>City1</tmn:City>
<Address>
<pn2:PermAddress xmlns:pn2="http://www.blah2.com/"
>Address1</pn2:PermAddress>
<tmn:Street StreetID=" " scID=" " ID=" "
xmlns:tmn="http://www.blah.com/"
>Street1</tmn:Street>
<pn:Estate StateID=" " SID=" " ID=" " xmlns:pn="http://www.blah1.com/"
>Estate</pn:Estate>
<pn3:Place xmlns:pn3="http://www.blah3.com/">Place</pn3:Place>
</Address>
</Details>
</soap-env:Body>
</soap-env:Envelope>
XSLT I tried:
<xsl:template match="Details//*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="Details//@*">
<xsl:copy-of select="."/>
</xsl:template>
I'm able to remove namespaces but not elements in my XSLT.
Upvotes: 0
Views: 423
Reputation: 117140
Here is one way you could look at it:
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="*"/>
<xsl:template match="*">
<!-- exclude text nodes -->
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*[not(namespace-uri()) or starts-with(name(), 'pn2:') or starts-with(name(), 'pn3:')]">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
A smarter way might be to ignore the prefixes and base the selection on the actual namespace URIs - i.e.:
<xsl:template match="*[not(namespace-uri()) or namespace-uri()='http://www.blah2.com/' or namespace-uri()='http://www.blah3.com/']">
Upvotes: 3