A little tricky to explain what I am trying to do, so I will use an over-simplified example.
I have three Xsl-templates: A.xsl, B.xsl and Common.xsl
Both A.xsl and B.xsl use "xsl:include" to include Common.xsl. A.xsl looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tns="http://MyNamespaceForA" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:include href="Common.xslt"/>
<xsl:template match="/">
<tns:RootA>
<xsl:apply-templates select="Root" />
</tns:RootA>
</xsl:template>
</xsl:stylesheet>
B.xls looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tns="http://MyNamespaceForB" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:include href="Common.xslt"/>
<xsl:template match="/">
<tns:RootB>
<xsl:apply-templates select="Root" />
</tns:RootB>
</xsl:template>
</xsl:stylesheet>
Finally, Common.xls looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="Root">
<tns:Element>
<tns:SubElement>
</tns:SubElement>
</tns:Element>
</xsl:template>
</xsl:stylesheet>
So, A and B look different, they use the same namespace prefix (tns) but the namespaces have different values. A and B includes Common.xsl, which also uses the tns namespace.
In other words, I want the tns namespace in Common.xsl to take the value of the "calling", i.e. A or B, xsl-file.
However, this doesn't work when using XslCompiledTransform, it complains that tns is an undeclared namespace when in Common.xsl. If I declare the tns namespace in Common.xsl, I need to use either http://MyNamespaceForA
or http://MyNamespaceForB
.
Let's say I declare tns as http://MyNamespaceForB
in Common.xsl. Now, when I use A.xsl, there will be conflicting values of the tns namespaces. The effect will be that the XML elements generated by Common.xsl will have an explicit namespace value of http://MyNamespaceForB
. That won't work, of course.
Hope I am somewhat clear what I am trying to do. In short, I want to have the "calling" xsl-file dictate the value of a namespace in an included xsl-file.
Any ideas? /Fredrik
If you use a direct namespace in Common.xslt you MUST declare the namespace in the same file, otherwise it won't be valid XML - no way the XSLT processor can load it.
The solution is to use
xsl:element
to create the elements and use a variable for the target namespaceA.xslt:
Common.xslt: