omer khalid
omer khalid

Reputation: 895

Trouble Inserting an element into xml using XSLT 2.0

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

Answers (1)

Linga Murthy C S
Linga Murthy C S

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

Related Questions