I'm totally new to XSL and have the task of generating output xml with xmlns:A.B.C prefix/value as an attribute of the root node. Specifically like this:
<GetVersionResponse xmlns:A.B.C="www.somesite.co.uk/A/B/C">
<Class>GetVersionRequest</Class>
<Errors>
<Error>
<Text>Some message</Text>
</Error>
</Errors>
</GetVersionResponse>
This is my input:
<Error>
<Namespace>xmlns:A.B.C</Namespace>
<NamespaceValue>www.somesite.com/A/B/C</NamespaceValue>
<Class>GetVersionRequest</Class>
<Message>Some message</Message>
</Error>
This is the important snippet from the Error.xsl file:
<xsl:template match="Error">
<xsl:variable name="ResponseType">
<xsl:value-of select="concat(substring-before(Class, 'Request'),'Response')"/>
</xsl:variable>
<xsl:variable name="NS">
<xsl:value-of select="Namespace"/>
</xsl:variable>
<xsl:variable name="NSV">
<xsl:value-of select="NamespaceValue"/>
</xsl:variable>
<xsl:element name="{$ResponseType}" namespace="{$NSV}" xml:space="default">
...
</xsl:template
It generates the following error because I have a colon in the Namespace element of my input:
XSLT 2.0 Debugging Error: Unknown namespace prefix
If I replace the colon with an underscore I get the exact out put I require but only with an underscore of course. Like this:
<GetVersionResponse xmlns_A.B.C="www.somesite.co.uk/A/B/C">
<Class>GetVersionRequest</Class>
<Errors>
<Error>
<Text>Some message</Text>
</Error>
</Errors>
</GetVersionResponse>
I've trawled the web for hours and think I'm trying to insert the xmlns: as text instead of using the proper objects that will generate xmlns:MYTEXT but cannot figure out how to do it.
Many Thanks for any help !!!!
The complicating factor here is that xmlns:...
namespace declarations are not attributes as far as the XPath data model is concerned, so you can't create them using xsl:attribute
. However, in XSLT 2.0 you can create them using xsl:namespace
.
<xsl:template match="Error">
<xsl:element name="{substring-before(Class, 'Request')}Response">
<xsl:namespace name="{substring-after(Namespace, 'xmlns:')}"
select="NamespaceValue" />
<xsl:copy-of select="Class" />
<Errors>
<Error>
<Text><xsl:value-of select="Message" /></Text>
</Error>
</Errors>
</xsl:element>
</xsl:template>
The name
attribute of xsl:namespace
is the prefix you want to bind (so not including xmlns:
), and the select
gives the URI you want to bind it to.