The main thing is to understand that your stylesheet defines the name of each element that is added to the resulting tree. The element name consists of two parts: the local name and the namespace URI. In the above code, you specify the local name (the value is $xmlElem ), but you do not specify the namespace URI, which means that by default it will contain an empty string. (In fact, this takes up the default namespace for this style sheet module, since it is not there, then this is an empty string.) In other words, the element will not be in the namespace. When serializing a document, the XSLT processor must include xmlns="" un-declarations in order to decompress the default namespace that appears at the top. Otherwise, the element will occupy this namespace, which does not match your type. The least intrusive way to do this would be to add another parameter (e.g. $namespaceURI ), like you have with $xmlElem . Then you should write:
<xsl:element name="{$xmlElem}" namespace="{$namespaceURI}">
Now the resulting element will take on whatever namespace you tell it (which will remove these default declarations for the namespace).
This should answer your question. I offer the following as a free bonus material .; -)
You must remove the text() node test in the comparison of values. Very rarely, you will need to directly compare the values ββof text nodes. Instead, you can simply compare the string value of the element itself (which is defined as the concatenation of the string values ββof all its streaming text nodes). It will look like this:
<xsl:when test="/databean/data[@id='pkhfeed']/value = '200'">
The advantage of this method is that your code will not break if a comment is hidden there:
<value>200</value>
In this case, there are two text nodes ("2" and "00"). Your original test will not work, as it checks to see if any of them match "200". In this case, it is unlikely to happen, but in any case, testing the string value of an element (in contrast to its node children text) is good practice when this is your intention.
Finally, I recommend that you learn about pattern rules and XPath context. I try to avoid <xsl:choose> , <xsl:call-template> and <xsl:with-param> whenever possible. First, template rules can help you avoid the many ugly, detailed parts of XSLT.
<xsl:template match="/databean[data[@id='pkhfeed']/value = '200']" priority="1"> <StructureA xmlns="http://..."> ... </StructureA> </xsl:template> <xsl:template match="/databean"> <StructureB xmlns="http://..."> ... </StructureB> </xsl:template>
Even if you continue to use <xsl:call-template> , you do not need to pass this parameter to $structure , as the current node will remain unchanged in the called template. You can access the //databean (or /databean , which I suspect is what you mean) as easily as in any of your StructureA or StructureB templates, since the current node will still be "/" (document node).
If you are interested in learning more about the XSLT core processing model and its most powerful features (template rules), I recommend that you check out βHow XSLT Worksβ , the chapter of a free sample from my Pocket XSLT 1.0 Pocket Reference.
I hope it was useful to you, even if it is more than you expected!