I am new to XSLT transformation. I have namepace mapping issue in my output xml.
The input XML is
<m:class xmlns:m="http://www.NotRequirednamespace.com">
<queryDetails>hello</queryDetails>
</m:class>
My XSLT is look like
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.neededNamespace.com" xmlns:t="http://www.NotRequirednamespace.com" exclude-result-prefixes="t">
<xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>
<!-- Stylesheet to remove all namespaces from a document -->
<!-- NOTE: this will lead to attribute name clash, if an element contains
two attributes with same local name but different namespace prefix -->
<!-- Nodes that cannot have a namespace are copied as such -->
<xsl:template match="/">
<school xmlns="http://www.neededNamespace.com">
<xsl:apply-templates/>
</school>
</xsl:template>
<!-- template to copy elements -->
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<!-- template to copy attributes -->
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!-- template to copy the rest of the nodes -->
<xsl:template match="comment() | text() | processing-instruction()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
The output XML is
<school xmlns="http://www.neededNamespace.com">
<class xmlns="">
<queryDetails>hello</queryDetails>
</class>
</school>
But I dont want the name default namespace (xmlns="") in the element class. I like to specify the default namespace for the class element as "http://www.neededNamespace.com". So that I need the output xml as follows.
<school xmlns="http://www.neededNamespace.com">
<class>
<queryDetails>hello</queryDetails>
</class>
</school>
I have tried all the options i know. Can you help in this. Thanks in advance.
Do you really need all that code? Or are you just using this as an incantation, in the hope it will somehow appease the evil spirits? Like what does xpath-default-namespace do in an XSLT 1.0 stylesheet? (Answer: either nothing, or produce a fatal error - depending on how tolerant your processor is).
Now, if your XML example is representative, then all you need to do is:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.neededNamespace.com">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<school>
<xsl:apply-templates/>
</school>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
What this does is:
<school>;Since the stylesheet contains a declaration of a default namespace, ALL newly created elements (in both #1 and #2 above) will be placed in that namespace.
Since your input does not include any attributes, that should be all the code that's required.
In case you worry they may add some attributes in the future that you wish to pass to the output, just change the second template to:
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
This assumes the attributes will be in no namespace - and that's a very reasonable assumption. Attributes do not inherit their parent's namespace, and very rarely do you see authors place attributes in namespaces explicitly. Only if you really need to anticipate such possibility do you need additional code to handle the attributes.
So you don't want to remove the namespace of the "class" element, you want to change it. Use the "namespace" attribute of the xsl:element node.
Instead of
<xsl:element name="{local-name()}">
you want
<xsl:element name="{local-name()}" namespace="http://www.neededNamespace.com">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With