Reputation: 11
I wish to remove a couple of unused namespaces from a resulting output from an xslt stylesheet.
The xml to feed in is a wrapper around another xml message which is seen in the BodyMessage element. An example of the entire xml can bee seen below:
<?xml version="1.0" encoding="utf-8"?>
<ns0:Wrapper xmlns:ns0="http://ref.fairyliquidplc.ads/Schema/Fairy/Wrapper/1.0" xmlns:mco="http://ref.fairyliquidplc.ads/Schema/Fairy/Common/1.0">
<TaskName>SomeTaskName</TaskName>
<TaskStatus>Start</TaskStatus>
<Id>Y/0070/0010</Id>
<BodyMessage>
<tva:TVAMain rightsOwner="FAIRY" xmlns:tva="urn:tva:metadata:2004">
<tva:Colour>red</tva:Colour>
<tva:Size>12</tva:Size>
<tva:Style>Skinny</tva:Style>
<tva:Fabric>Denim</tva:Fabric>
</tva:TVAMain>
</BodyMessage>
</ns0:Wrapper>
When I try to extract the xml out of the BodyMessage element I get unused namespaces returned
xmlns:ns0="http://ref.fairyliquidplc.ads/Schema/Fairy/Wrapper/1.0"
xmlns:mco="http://ref.fairyliquidplc.ads/Schema/Fairy/Common/1.0"
These are not required but I do not understand how to remove them within my xslt.
Please note I DO want to keep
xmlns:tva="urn:tva:metadata:2004"
The stylesheet I used is:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tva="urn:tva:metadata:2004"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output encoding="UTF-8" method="xml" omit-xml-declaration="no" version="1.0" />
<xsl:template match="/">
<xsl:variable name="completeTva" select="//tva:TVAMain" />
<xsl:copy-of select ="$completeTva"/>
</xsl:template>
The output of the stylesheet is:
<?xml version="1.0" encoding="utf-8"?>
<tva:TVAMain rightsOwner="FAIRY" xmlns:tva="urn:tva:metadata:2004" xmlns:ns0="http://ref.fairyliquidplc.ads/Schema/Fairy/Wrapper/1.0" xmlns:mco="http://ref.fairyliquidplc.ads/Schema/Fairy/Common/1.0">
<tva:Colour>red</tva:Colour>
<tva:Size>12</tva:Size>
<tva:Style>Skinny</tva:Style>
<tva:Fabric>Denim</tva:Fabric>
What I require is:
<?xml version="1.0" encoding="utf-8"?>
<tva:TVAMain rightsOwner="FAIRY" xmlns:tva="urn:tva:metadata:2004">
<tva:Colour>red</tva:Colour>
<tva:Size>12</tva:Size>
<tva:Style>Skinny</tva:Style>
<tva:Fabric>Denim</tva:Fabric>
Any help would be greatly appreciated. :)
Upvotes: 1
Views: 1742
Reputation: 243459
This transformation (Sorry, this is a bug in the SO code-formatter!):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tva="urn:tva:metadata:2004"
xmlns:ns0="http://ref.fairyliquidplc.ads/Schema/Fairy/Wrapper/1.0"
xmlns:mco="http://ref.fairyliquidplc.ads/Schema/Fairy/Common/1.0"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vtoDiscard" select=
"document('')
/*/namespace::*[name()='ns0' or name()='mco']"/>
<xsl:template match="tva:*">
<xsl:element name="{name()}"
namespace="urn:tva:metadata:2004">
<xsl:copy-of select="namespace::*[not(. = $vtoDiscard)]"/>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="text()[not(ancestor::BodyMessage)]"/>
</xsl:stylesheet>
when applied on the provided XML document:
<ns0:Wrapper
xmlns:ns0="http://ref.fairyliquidplc.ads/Schema/Fairy/Wrapper/1.0"
xmlns:mco="http://ref.fairyliquidplc.ads/Schema/Fairy/Common/1.0">
<TaskName>SomeTaskName</TaskName>
<TaskStatus>Start</TaskStatus>
<Id>Y/0070/0010</Id>
<BodyMessage>
<tva:TVAMain rightsOwner="FAIRY"
xmlns:tva="urn:tva:metadata:2004">
<tva:Colour>red</tva:Colour>
<tva:Size>12</tva:Size>
<tva:Style>Skinny</tva:Style>
<tva:Fabric>Denim</tva:Fabric>
</tva:TVAMain>
</BodyMessage>
</ns0:Wrapper>
produces the wanted, correct result:
<tva:TVAMain xmlns:tva="urn:tva:metadata:2004" rightsOwner="FAIRY">
<tva:Colour>red</tva:Colour>
<tva:Size>12</tva:Size>
<tva:Style>Skinny</tva:Style>
<tva:Fabric>Denim</tva:Fabric>
</tva:TVAMain>
Explanation:
Both xsl:copy
and xsl:copy-of
copy an element together with the namespace nodes that belong to it.
The way to strip some namespace nodes off an element is to re-create it using the xsl:element
, then to copy from the original element only the wanted namespace nodes.
Upvotes: 1