Prabath Abeysekara
Prabath Abeysekara

Reputation: 1085

Construct an output XML based on a node set stored as a xsl:param

I have a requirement where I need to transform one XML document to another using a nodeset stored as a XSLT parameter.

Input:

<m:addCustomer xmlns:p="http://test.org"/>

Expected output format:

<m:addCustomer xmlns:p="http://test.org"/>
   <m:e1>some_value1</m:e1>
   <m:e2>some_value2</m:e2>
   <m:e3>some_value3</m:e3>
</m:addCustomer>

The issue I'm confronted with is, the only way I can pass the content of the "expected output" format, is via an XSLT parameter as follows.

<xsl:param name="testParam" xmlns:m="http://test.org">
    <m:customerData> 
         <m:e1>some_value1</m:e1>
         <m:e2>some_value2</m:e2>
         <m:e3>some_value3</m:e3>
    </m:customerData>
</xsl:param>

So far I've tried the following XSLT configuration without any success.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="utf-8" indent="no"/>
    <xsl:param name="testParam">
        <![CDATA[<m:customerData xmlns:m="http://cclk.lk">
    <m:e1>dfdf</m:e1>
    <m:e2>dfdf</m:e2>
    <m:e3>dfdf</m:e3></m:customer>]]>
    </xsl:param>
    <xsl:template match="/" xmlns:m="http://cclk.lk">
        <m:addCustomer>
            <xsl:value-of select="$testParam" disable-output-escaping="yes"/>
            <xsl:apply-templates select="m:customerData"/>
        </m:addCustomer>
    </xsl:template>

    <xsl:template match="m:customerData" xmlns:m="http://cclk.lk">
        <m:addUser>
            <xsl:for-each select="m:customer/*">
                <m:e1>
                    <xsl:value-of select="e1"/>
                </m:e1>
                <m:e2>
                    <xsl:value-of select="e2"/>
                </m:e2>
                <m:e3>
                    <xsl:value-of select="e3"/>
                </m:e3>
            </xsl:for-each>
        </m:addUser>
    </xsl:template>
</xsl:stylesheet>

Currently I'm unable to figure out a way to do this. Appreciate any help on this.

Regards, Prabath

Upvotes: 1

Views: 110

Answers (1)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243529

The parameter as specified:

<xsl:param name="testParam" xmlns:m="http://test.org">
    <m:customerData> 
         <m:e1>some_value1</m:e1>
         <m:e2>some_value2</m:e2>
         <m:e3>some_value3</m:e3>
    </m:customerData>
</xsl:param>

in XSLT 1.0 creates an RTF (Result Tree Fragment) -- a very restricted type, that forbids almost any meaningful XPath expression evaluation.

The solution:

Use the vendor-provided extension function xxx:node-set(), which converts an RTF to a regular tree.

Do note, that this extension function name is in a vendor-defined namespace, which varies from vendor to vendor.

There is an attempt to provide a vendor-independent implementation -- the one defined in EXSLT:

ext:node-set()

where the prefix ext is bound to the namespace http://exslt.org/common.

Most XSLT 1.0 processors, including the .NET XslCompiledTransform, implement ext:node-set().


In case you don't want any extension function, then the solution is to use the standard XSLT 1.0 function document() like this:

document('')/*/xsl:param[@name='testParam']

Upvotes: 2

Related Questions