I have an xml document where some of the elements have a namespace and others do not. All of them need namespaces, some the same some different. The elements have properties which I want to keep.
The xml:
<foo xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gco="http://www.isotc211.org/2005/gco" xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd" xmlns="http://www.isotc211.org/2005/gmd">
<bar y="2">
<baz z="3"/></bar>
<a-special-element n="8"/>
<another-special-element k="8"/>
</foo>
And the xslt:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="*">
<xsl:element name="{local-name()}" namespace="A" >
<xsl:copy-of select="attribute::*"/>
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="foo">
<xx:foo xmlns:xx="xx">
<xsl:apply-templates/>
</xx:foo>
</xsl:template>
<xsl:template match="a-special-element">
<B:a-special-element xmlns:B="B">
<xsl:apply-templates/>
</B:a-special-element>
</xsl:template>
<xsl:template match="another-special-element">
<C:a-special-element xmlns:C="C">
<xsl:apply-templates/>
</C:another-special-element>
</xsl:template>
</xsl:stylesheet>
Here is the output i would like to have:
<xx:foo xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gco="http://www.isotc211.org/2005/gco" xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd" xmlns="http://www.isotc211.org/2005/gmd"> <bar y="2">
<baz z="3"/>
</bar>
<B:a-special-element n="8"/>
<C:another-special-element k="4"/>
</xx:foo>
I checked out this thread but there the property of the “a-special-element” has been magically removed. Add a namespace to elements
Also I have multiple xmlns:??? in the foo that I want to keep.
First of all: namespaces are a fundamental concept in XML. If you are not familiar with namespaces, please take time to learn and understand them.
Actually in your code sample all the elements belong to a namespace.
Code
xmlns="http://www.isotc211.org/2005/gmd"in your root element defines a default namespace with URI"http://www.isotc211.org/2005/gmd". Thus this element and its descendants belong to this default namespace if the element name doesn’t have a namespace prefix. It’s easy to forget that an element is in some namespace, if it uses the default namespace, because there is no namespace prefix. Note that default namespace doesn’t apply to attributes, only elements.Your expected result document is not clear. It should also have namespace definitions for the namespace prefixes
xx,BandC. I also assumed that your namespaceAis the same as the default namespace used your expected result document.Anyway, given this input:
This XSLT code:
Will produce this output:
Notice how an identity template is used to recursively copy the contents of the input document which is a common and useful technique.
Note that the default namespace of the XSLT document doesn’t apply to element names used in
<xsl:template match="ELEMENT-NAME">. Therefore you need to define a namespace prefix for the default namespace of the input document and use that prefix when you refer to those elements, for example in thematchandselectattributes. Also note that because of this, the namespace URIhttp://www.isotc211.org/2005/gmdis defined twice in the result document – with the prefixgmdand as a default namespace. If this bothers you, you can addexclude-result-prefixes="gmd"attribute to the<xsl:stylesheet>element. As a side effect, this could cause your default namespace definition appear later in the document and not in the root element but that is just a visual difference, the underlying functionality stays the same.