Reputation: 459
I want to copy the namespaces in the elements. The namespace attribute and its value may vary and can occur in any element. But I want to copy the namespace as it is. Also I should not include any attribute as additional to copy the namespace. I am using Saxon 9(he) XSLT processor for transformations
In the below XML file, I am getting the element <ct-ext:case>
with the "xmlns:ct-ext"
attribute missing. I tried copy-namespaces="yes"
, yet I am not getting the correct output. I am writing a common XSLT for various DTDs.
Sample XML:
<?xml version="1.0" encoding="UTF-8"?>
<ct:doc identifier="GPPCIA702661235" xsi:schemaLocation="http://test.com/test test.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ct="http://test.com/test" xmlns="http://www.w3.org/1998/Math/MathML" xmlns:ct-ext="http://test.com/test-ext">
<ct:doc-meta identifier="EHIXRW383636159">
<ct:para><ct:inline-math identifier="RCSNDD453018159"><math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>$</mi><mn>1.65</mn></mrow></math></ct:inline-math></ct:para>
<ct-ext:case identifier="CDVOXU875594216" xmlns:ct-ext="http://test.com/test-ext">
<ct:simple-meta identifier="HNKRFT326435269">
<ct:title identifier="CGSVLX990515344">This is title</ct:title>
</ct:simple-meta>
</ct-ext:case>
</ct:doc-meta>
</ct:doc>
Output Required:
<?xml version="1.0" encoding="UTF-8"?>
<ct:doc identifier="GPPCIA702661235" xsi:schemaLocation="http://test.com/test test.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ct="http://test.com/test" xmlns="http://www.w3.org/1998/Math/MathML" xmlns:ct-ext="http://test.com/test-ext">
<ct:doc-meta identifier="EHIXRW383636159">
<ct:para><ct:inline-math identifier="RCSNDD453018159"><math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>$</mi><mn>1.65</mn></mrow></math></ct:inline-math></ct:para>
<ct-ext:case identifier="CDVOXU875594216" xmlns:ct-ext="http://test.com/test-ext">
<ct:simple-meta identifier="HNKRFT326435269">
<ct:title identifier="CGSVLX990515344">This is title</ct:title>
</ct:simple-meta>
</ct-ext:case>
</ct:doc-meta>
</ct:doc>
XSLT tried:
<?xml version='1.0'?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ct="http://test.com/test" xmlns="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:ct-ext="http://test.com/test-ext">
<xsl:output method="xml" encoding="UTF-8" indent="no"/>
<xsl:template match="@*|node()">
<xsl:copy copy-namespaces="yes">
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 1672
Reputation: 27996
To elaborate on what Martin said: you are putting requirements on XML tools (like XSLT) that they're not designed to fulfill.
It will help if we use more precise terminology. What you're asking to copy are not namespaces, but rather namespace declarations.
XML tools are designed to be able to produce specified XML elements (and other nodes) in the namespaces that you specify them to be in. This is part of the XML information model. XML tools are not required to let you specify what namespace prefixes to use, or where to put namespace declarations, so long as the output XML has the right elements and attributes in the right namespaces.
So the requirements you're specifying should not be necessary for any downstream XML consumer. Maybe if you explain why you want namespace declarations to come out in a certain way, we can help you find ways to achieve those purposes, ways that are compatible with how XML namespaces are designed to work.
Upvotes: 1
Reputation: 167436
Whether you use copy-namespaces
or not does not matter (yes is the default anyway), if the input XML has a duplicated namespace declaration on an inner element node then the data model the XSLT processor operates on is not different from the one produced if the inner namespace declaration were not present.
So
<root xmlns:ct-ext="http://test.com/test-ext">
<ct-ext:case xmlns:ct-ext="http://test.com/test-ext">...</ct-ext:case>
</root>
does not differ from
<root xmlns:ct-ext="http://test.com/test-ext">
<ct-ext:case>...</ct-ext:case>
</root>
Consequently when serializing the copied result tree the originally duplicated namespace declaration is lost. I don't think there is a way with XSLT to prevent that.
Upvotes: 1