Reputation: 895
I am receiving a soap message(XML) and after adding a new XML element i have to send it further to another service. Is it possible to add the element by using XSLT 2.0. If so then how?
Input Message
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<tns:GLBookingMessage xmlns:tns="http://com.example/cdm/finance/generalledger/v1">
<tns:GLBooking>
</tns:GLBooking>
</tns:GLBookingMessage>
</soapenv:Body>
</soapenv:Envelope>
Required Output Message:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<tns:GLBookingMessage xmlns:tns="http://com.example/cdm/finance/generalledger/v1">
<CHeader>
</CHeader>
<tns:GLBooking>
</tns:GLBooking>
</tns:GLBookingMessage>
</soapenv:Body>
</soapenv:Envelope>
XSLT Sheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cdm="http://com.example//cdm/finance/generalledger/v1"
xmlns:tns="http://com.example//cdm/finance/generalledger/v1"
xmlns:cur="http://com.example//cdm/currencycodes/v1"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
>
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//GLBookingMessage">
<GLBookingMessage>
<xsl:copy-of select="."/>
<CHeader>
</CHeader>
</GLBookingMessage>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Views: 121
Reputation: 5432
Try this:
The first template copies all the attributes and nodes as it is.
Since the tns:GLBookingMessage
element is the one that needs change, we have a template for that(this template gets precedence over the first template), in which we use xsl:copy
to create the tag(tns:GLBookingMessage
), apply-templates for attributes(to copy attributes, not required in your case).
Then, add the new element CHeader
and the again apply-templates for all the nodes(), which is going to call the first template, thereby copying all the children of tns:GLBookingMessage
as they are..
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tns="http://com.example/cdm/finance/generalledger/v1">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tns:GLBookingMessage">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<CHeader/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Your namespaces in XSLT aren't matching in your Input XML.. after correcting these, you could have moved <CHeader/>
above copy-of
and by changing the copy-of
to
<xsl:copy-of select="*"/>
But my answer makes good use of the identity template(the first template) for copying..
Upvotes: 1