Reputation: 1085
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
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:
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