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
The parameter as specified:
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
extis bound to the namespacehttp://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: