Reputation: 1624
I am trying to write an xslt transform that does not include any @xmlns:* attributes in the root element of the output. Given this xml :
<?xml version="1.0" encoding="UTF-8"?>
<jw:root xmlns:jw="http://lexisnexis.com/neptune/gtdttest/jw">
<jw:a/>
<b test="1">
<c/>
</b>
</jw:root>
and this stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.0"
xmlns:jw="http://namespace/test/jw" exclude-result-prefixes="jw">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@test"/>
</xsl:stylesheet>
I'm getting this:
<?xml version="1.0" encoding="UTF-8"?>
<jw:root xmlns:jw="http://lexisnexis.com/neptune/gtdttest/jw">
<jw:a/>
<b>
<c/>
</b>
</jw:root>
I tried - putting the @exclude-result-prefixes on the root template, - not copying the attributes, - not using 'copy' in identity template but using - using #all
I read in the spec, although I can't find it now, that <xsl:copy/>
ignores @exclude-result-prefixes, and that other thing can override it as well.
any way to remove those @xmlns:[prefix] atts? The ns's are defined in the dtd that the output uses, and it screws me up to have them there. Guess I will have to make a separate pass just opening with java and remove that way?
thanks!
Upvotes: 2
Views: 8708
Reputation: 31011
Instead of the identity template use the following:
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
If your source XML has also attributes with namespaces, then add also the following template:
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
Of course, this approach works as long as you have no "ovelapping" element / attribute names (same name with diffrent namespaces).
Upvotes: 3
Reputation: 163595
The exclude-result-prefixes attribute (a) only works for literal result elements, and (b) only eliminates namespaces that are unused - a namespace that is used in the name of an element or attribute will always be declared in the result tree.
What you are trying to achieve is to modify the input elements to be in a different namespace. That can't be done with xsl:copy, which always keeps the name of the elements (namespace + local name) intact. You need to create a new element using <xsl:element name="{local-name()}">
.
If you give your result elements and attributes the right name, the namespace declarations will take care of themselves. Remember that the name of an element or attribute is a (namespace, localname) pair.
Upvotes: 6