Mark
Mark

Reputation: 2504

how can i add a variable namespace to an element using xslt

I am trying to set a namespace on a soapenv:Header element that changes based on a param passed into xslt.

Here is my template I am using and the expected output is below.

The input to the xslt are the 3 params which contain a namespace, that varies, request method and the body of the message, which is just copied.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="xs"
        version="2.0">
    <xsl:param name="RequestNameSpace" />
    <xsl:param name="RequestMethod"/>
    <xsl:param name="RequestMessageBody" />

    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="/" >
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myns="{$RequestNameSpace}">
            <soapenv:Header/>
            <soapenv:Body>
                <xsl:element name="myns:{$RequestMethod}">
                    <xsl:copy-of select="$RequestMessageBody" />
                </xsl:element>
            </soapenv:Body>
        </soapenv:Envelope>

    </xsl:template>
</xsl:stylesheet>

Current output, note in the soapenv:Envelope tag the namespace was not applied, what Im after is for the RequestNameSpace to be applied as it was passed in.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myns="{$RequestNameSpace}">
<soapenv:Header/>
<soapenv:Body>
    <myns:hello_world>
       <test_tag>Test output</test_tag>
    </myns:hello_world>
</soapenv:Body>
</soapenv:Envelope>

If anyone can point out what im doing wrong, would be great. I belive it has something to do with that fact im not using a xsl: type element for the soapenv:Envelop element, but im not sure how I go about declaring it and having the namespaces included.

Cheers

Upvotes: 0

Views: 1303

Answers (2)

Michael Kay
Michael Kay

Reputation: 163645

In XSLT 2.0, use the xsl:namespace instruction, for example <xsl:namespace name="prefix" select="$requiredNamespace"/>.

If you're stuck with XSLT 1.0, you can create a dummy element (in a variable) in the required namespace using <xsl:element name="x:dummy" namespace="{$requiredNamespace}"/>, and then, with the help of the exslt:node-set() extension and the namespace axis, you can find the relevant namespace node within this result-tree fragment and copy it to the required element using something like <xsl:copy-of select="exslt:node-set($variable)//namespace::x)"/>

Upvotes: 0

michael.hor257k
michael.hor257k

Reputation: 117175

Why don't you use:

<xsl:element name="{$RequestMethod}" namespace="{$RequestNameSpace}">
    <xsl:copy-of select="$RequestMessageBody" />
</xsl:element>

Upvotes: 1

Related Questions