0

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

2 Answers 2

1

Why don't you use:

<xsl:element name="{$RequestMethod}" namespace="{$RequestNameSpace}">
    <xsl:copy-of select="$RequestMessageBody" />
</xsl:element>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Michael, cheers it works a treat. I'm fairly new to xslt and xml for that matter and didn't realise just moving the namespace declaration into the relevant node would work as well.
0

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)"/>

3 Comments

Thanks Michael, this xslt is much more complex than it looks, unfortunately, I'm stuck with default camel library which is xslt 1.0 for the moment. I've gone for simplicity and used michael.hor257k answer as it works and in much simpler to look at. no exslt hocus pocus going on.
@Mark Note that your stylesheet declares version 2.0 (which is the only hint your question provides regarding the version your processor is using...).
Thanks michael i realised that when i revisited it today

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.