I am trying to rename a tag, using XSLT in WSO2 ESB template.
All my attempts get me the same error: Unable to create an OMElement using XSLT result.
One of the variants I have tried is:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:param name="response_tag"/>
<xsl:template match="RESPONSE">
<xsl:element name="{$response_tag}" >
<xsl:for-each select="/RESPONSE/*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Another is:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="request_tag"/>
<xsl:template match="RESPONSE">
<xsl:element name="{$request_tag}">
<xsl:apply-templates select="node() | @*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
What am I doing wrong?
PS. The parameter response_tag
value is similar to rns:NameOfResponse
The namespace (rns
) and NameOfResponse
could be different every time. The namespace is inside the Envelope tag of the xml, so in the end (if the transformation works), the xml would be valid.
The input will be something like:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rns="http://www.example.com/example">
<soapenv:Header/>
<soapenv:Body>
<RESPONSE xmlns="http://ws.apache.org/ns/synapse">
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
...
</RESPONSE>
</soapenv:Body>
</soapenv:Envelope>
The result should be:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rns="http://www.example.com/example">
<soapenv:Header/>
<soapenv:Body>
<rns:NameOfResponse>
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
...
</rns:NameOfResponse>
</soapenv:Body>
</soapenv:Envelope>
PPS. Tried removing the namespace from the response tag - i.e. the response tag looks like: NameOfTag
now. Same error.
I am guessing you want to do something like this:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:syn="http://ws.apache.org/ns/synapse"
xmlns="http://www.example.com/example"
exclude-result-prefixes="syn">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="response_tag"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="syn:RESPONSE">
<xsl:element name="{substring-after($response_tag, ':')}" >
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="syn:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Applied to your input example, with a parameter response_tag='rns:NameOfResponse'
, the result will be:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<NameOfResponse xmlns="http://www.example.com/example">
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
...
</NameOfResponse>
</soapenv:Body>
</soapenv:Envelope>
Please note that the NameOfResponse
element declares a default namespace - and this is inherited by its descendants, in the same way as in your input.
To get the exact output shown in your question, you can do:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:syn="http://ws.apache.org/ns/synapse"
exclude-result-prefixes="syn">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="response_tag"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="syn:RESPONSE">
<xsl:element name="{$response_tag}" namespace="http://www.example.com/example">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="syn:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Caveat: I know nothing about WSO2; this is how it's supposed to work in XSLT.