'XSLT Transformation to create xml with cdata section
Iam trying to do xslt transformation with cdata section in it.I need to put the transformed xml in to aXMLInput tag as cdata section.iam able to create the xml successfully.Can you please tell me how to create the content in aXMLInput as cdata section.Attached Input xml,Expected output,xslt and Actual output. Thanks in Adavance.
Input XML :
<?xml version="1.0" encoding="UTF-8"?>
<ns2:esbMessage xmlns:ns2="http://messagev2.esb.company.com/">
<header>
<identity>
<master-id/>
<source-id/>
<user-id>calleruname</user-id>
</identity>
<esb-service-name>Pricing</esb-service-name>
<source-system-id>caller</source-system-id>
<message-type>REQ</message-type>
<message-id>ID-GCSW01987-49931-1484306332450-6-131</message-id>
</header>
<body>
<request>
<esb-metadata>
<user-id>calleruname</user-id>
<service-name>Pricing</service-name>
<source-system-id>caller</source-system-id>
</esb-metadata>
<message-body>
<rating-request xmlns:urn1="urn:company:esb:services:Rating:v01">
<fo>
<policy>
<provider-input>
<account-complexity code="med" description="Medium" source-system=" CUBE"/>
<primary-sic-code>2052-cook and crackers</primary-sic-code>
<policy-inception-date>2016-12-23</policy-inception-date>
<policy-expiration-date>2017-12-23</policy-expiration-date>
<requested-deductible>
<amount>1000.00</amount>
<currency>USD</currency>
</requested-deductible>
<requested-deductible>
<amount>1000.00</amount>
<currency>USD</currency>
</requested-deductible>
</provider-input>
</policy>
</fo>
</rating-request>
</message-body>
</request>
</body>
</ns2:esbMessage>
Expected Output:
<ns2:esbMessage xmlns:ns2="http://messagev2.esb.company.com/">
<header>
<identity>
<master-id/>
<source-id/>
<user-id>calleruname</user-id>
</identity>
<esb-service-name>Pricing</esb-service-name>
<source-system-id>caller</source-system-id>
<message-type>REQ</message-type>
<message-id>ID-GCSW01987-49931-1484306332450-6-131</message-id>
</header>
<body>
<rate:companyrating xmlns:rate="http://rateservices.provider.com/">
<aAddRoot>1</aAddRoot>
<aAddInputs>0</aAddInputs>
<aXMLInput><![CDATA[<rate lob="15">
<c i="0" desc="Policy">
<m i="2" n="PolicyInceptionDate" v="2016-12-23"/>
<m i="3" n="PolicyExpiryDate" v="2017-12-23"/>
<c i="1" desc="PropertyLine">
<m i="54" n="SICCode" v="2052-cook and crackers"/>
<m i="74" n="AccountSize" v="med"/>
</c>
</c>
</rate>]]></aXMLInput>
</rate:companyrating>
</body>
</ns2:esbMessage>
XSLT :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" xpath-default-namespace="yes"> </xsl:output>
<xsl:template match="/">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="body/request">
<rate:companyrating xmlns:rate="http://rateservices.provider.com/">
<aAddRoot>1</aAddRoot>
<aAddInputs>0</aAddInputs>
<xsl:apply-templates select="*"/>
</rate:companyrating>
</xsl:template>
<xsl:template match="body/request/esb-metadata">
</xsl:template>
<xsl:template match="body/request/message-body">
<aXMLInput>
<rate lob="15">
<c i="0" desc="Policy">
<xsl:call-template name="policy-inception-date"/>
<xsl:call-template name="policy-expiration-date"/>
<xsl:call-template name="primary-sic-code"/>
</c>
</rate>
</aXMLInput>
</xsl:template>
<xsl:template name="policy-inception-date">
<m>
<xsl:attribute name="i"><xsl:value-of select="2"/></xsl:attribute>
<xsl:attribute name="n"><xsl:value-of select="'PolicyInceptionDate'"/></xsl:attribute>
<xsl:attribute name="v"><xsl:value-of select='rating-request/fo/policy/provider-input/policy-inception-date'/></xsl:attribute>
</m>
</xsl:template>
<xsl:template name="policy-expiration-date">
<m>
<xsl:attribute name="i"><xsl:value-of select="3"/></xsl:attribute>
<xsl:attribute name="n"><xsl:value-of select="'PolicyExpiryDate'"/></xsl:attribute>
<xsl:attribute name="v"><xsl:value-of select='rating-request/fo/policy/provider-input/policy-expiration-date'/></xsl:attribute>
</m>
</xsl:template>
<xsl:template name="primary-sic-code">
<c i="1" desc="PropertyLine">
<m>
<xsl:attribute name="i"><xsl:value-of select="54"/></xsl:attribute>
<xsl:attribute name="n"><xsl:value-of select="'SICCode'"/></xsl:attribute>
<xsl:attribute name="v"><xsl:value-of select='rating-request/fo/policy/provider-input/primary-sic-code'/></xsl:attribute>
</m>
<m i="74" n="AccountSize" v="med"/>
</c>
</xsl:template>
<xsl:template match="* | @*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Actual output:
<?xml version="1.0" encoding="UTF-8"?>
<ns2:esbMessage xmlns:ns2="http://messagev2.esb.company.com/">
<header>
<identity>
<master-id/>
<source-id/>
<user-id>calleruname</user-id>
</identity>
<esb-service-name>Pricing</esb-service-name>
<source-system-id>caller</source-system-id>
<message-type>REQ</message-type>
<message-id>ID-GCSW01987-49931-1484306332450-6-131</message-id>
</header>
<body>
<rate:companyrating xmlns:rate="http://rateservices.provider.com/">
<aAddRoot>1</aAddRoot>
<aAddInputs>0</aAddInputs>
<aXMLInput>
<rate lob="15">
<c i="0" desc="Policy">
<m i="2" n="PolicyInceptionDate" v="2016-12-23"/>
<m i="3" n="PolicyExpiryDate" v="2017-12-23"/>
<c i="1" desc="PropertyLine">
<m i="54" n="SICCode" v="2052-cook and crackers"/>
<m i="74" n="AccountSize" v="med"/>
</c>
</c>
</rate>
</aXMLInput>
</rate:companyrating>
</body>
</ns2:esbMessage>
Solution 1:[1]
If you use a Saxon version like 9.6 or 9.7 supporting the XPath 3.0 serialize
function (https://www.w3.org/TR/xpath-functions-30/#func-serialize) then you can change the template to
<xsl:template match="body/request/message-body">
<aXMLInput>
<xsl:variable name="xml-data">
<rate lob="15">
<c i="0" desc="Policy">
<xsl:call-template name="policy-inception-date"/>
<xsl:call-template name="policy-expiration-date"/>
<xsl:call-template name="primary-sic-code"/>
</c>
</rate>
</xsl:variable>
<xsl:value-of select="serialize($xml-data)"/>
</aXMLInput>
</xsl:template>
and make sure you set
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" cdata-section-elements="aXMLInput"/>
In older versions of Saxon you might be able to use an extension function to do a similar job.
Solution 2:[2]
You need to add a cdata-section-elements attribute to the output tag as follows:
<xsl:output method="xml" cdata-section-elements="aXMLInput" version="1.0" encoding="UTF-8" indent="yes" xpath-default-namespace="yes"> </xsl:output>
This will wrap the contents of aXMLInput as CDATA. You may need to specify the contents as /text() For more info see https://www.xmltutorial.info/xslt/how-to-output-cdata-with-xsl/
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Martin Honnen |
Solution 2 | Ted Keenan |