Hitesh Gupta
Hitesh Gupta

Reputation: 73

Values are not present in transformed xml in xslt transformation

I am trying to transform one xml using xslt but I am getting empty xml nodes. Please let me know what I am missing.

My source xml is:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:ProcessPartsOrder xmlns="http://www.host.com/ERP/Sales/Entities" xmlns:ns2="http://www.host.com/ERP/Sales/ProcessPartsOrder" xmlns:ns4="http://www.host.com/ERP/Sales/ValueObjects" xmlns:ns3="http://www.host.com/ERP/Sales/Aggregates/PartsOrder">
    <ns2:MessageHeader>
        <CultureCode>en-US</CultureCode>
        <SenderNameCode>S3</SenderNameCode>
        <CreationDateTime>2019-03-19T22:48:16</CreationDateTime>
        <BODID>e27c5244-4f18-4343-a15f-e509b8a75802</BODID>
    </ns2:MessageHeader>    
</ns2:ProcessPartsOrder>

I want to transform into below format:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:proc="http://www.host.com/ERP/Sales/ProcessPartsOrder" xmlns:ent="http://www.host.com/ERP/Sales/Entities" xmlns:par="http://www.host.com/ERP/Sales/Aggregates/PartsOrder" xmlns:val="http://www.host.com/ERP/Sales/ValueObjects">
  <soapenv:Header/>
  <soapenv:Body>
    <proc:ProcessPartsOrder>
      <proc:MessageHeader>
        <ent:CultureCode>en-US</ent:CultureCode>
        <ent:SenderNameCode>S3</ent:SenderNameCode>
        <ent:CreationDateTime>2013-01-23T12:41:36-05:00</ent:CreationDateTime>
        <ent:BODID>e27c5244-4f18-4343-a15f-e509b8a75802</ent:BODID>
      </proc:MessageHeader>      
    </proc:ProcessPartsOrder>
  </soapenv:Body>
</soapenv:Envelope>

My xslt looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns2="http://www.host.com/ERP/Sales/CustomerOrderManagement"
                xmlns:ns3="http://www.host.com/ERP/Sales/Aggregates/PartsOrder"
                xmlns:ns4="http://www.host.com/ERP/Sales/ValueObjects"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
 exclude-result-prefixes="ns2 ns3 ns4 xs">
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
  <xsl:template match="/*">
    <soapenv:Envelope xmlns="http://www.host.com/ERP/Sales/CustomerOrderManagement"
                      xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                      xmlns:proc="http://www.host.com/ERP/Sales/ProcessPartsOrder"
                      xmlns:ent="http://www.host.com/ERP/Sales/Entities"
                      xmlns:par="http://www.host.com/ERP/Sales/Aggregates/PartsOrder"
                      xmlns:val="http://www.host.com/ERP/Sales/ValueObjects">
      <soapenv:Header/>
      <soapenv:Body>
        <proc:ProcessPartsOrder>
          <proc:MessageHeader>
            <ent:CultureCode>
              <xsl:value-of select="/ns2:ProcessPartsOrder/ns2:MessageHeader/CultureCode"/>
            </ent:CultureCode>
            <ent:SenderNameCode>
              <xsl:value-of select="ns2:ProcessPartsOrder/ns2:MessageHeader/SenderNameCode"/>
            </ent:SenderNameCode>
            <ent:CreationDateTime>
              <xsl:value-of select="ns2:ProcessPartsOrder/ns2:MessageHeader/CreationDateTime"/>
            </ent:CreationDateTime>
            <ent:BODID>
              <xsl:value-of select="ns2:ProcessPartsOrder/ns2:MessageHeader/BODID"/>
            </ent:BODID>
          </proc:MessageHeader>          
        </proc:ProcessPartsOrder>
      </soapenv:Body>
    </soapenv:Envelope>
  </xsl:template>
</xsl:stylesheet>

All I am getting an expected xml with empty values. I believe I am missing something for which I need help.

Thanks.

Upvotes: 1

Views: 114

Answers (1)

zx485
zx485

Reputation: 29042

You were giving the XPaths to the values a different namespace than in the source. Hence they return empty. The namespace itself differs.

In your source you define the default namespace as

xmlns="http://www.host.com/ERP/Sales/Entities"

But the ns2 namespace in the XSLT is defined as

xmlns:ns2="http://www.host.com/ERP/Sales/CustomerOrderManagement"

Or course you have to use the same namespace in the XPath expression of the XSLT. There you defined the first namespace as proc. So change your template to the following

<xsl:template match="/">
<soapenv:Envelope xmlns="http://www.host.com/ERP/Sales/CustomerOrderManagement"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:proc="http://www.host.com/ERP/Sales/ProcessPartsOrder"
                  xmlns:ent="http://www.host.com/ERP/Sales/Entities"
                  xmlns:par="http://www.host.com/ERP/Sales/Aggregates/PartsOrder"
                  xmlns:val="http://www.host.com/ERP/Sales/ValueObjects">
  <soapenv:Header/>
  <soapenv:Body>
    <proc:ProcessPartsOrder>
      <proc:MessageHeader>
        <ent:CultureCode>
          <xsl:value-of select="/proc:ProcessPartsOrder/proc:MessageHeader/ent:CultureCode"/>
        </ent:CultureCode>
        <ent:SenderNameCode>
          <xsl:value-of select="/proc:ProcessPartsOrder/proc:MessageHeader/ent:SenderNameCode"/>
        </ent:SenderNameCode>
        <ent:CreationDateTime>
          <xsl:value-of select="/proc:ProcessPartsOrder/proc:MessageHeader/ent:CreationDateTime"/>
        </ent:CreationDateTime>
        <ent:BODID>
          <xsl:value-of select="/proc:ProcessPartsOrder/proc:MessageHeader/ent:BODID"/>
        </ent:BODID>
      </proc:MessageHeader>          
    </proc:ProcessPartsOrder>
  </soapenv:Body>
 </soapenv:Envelope>
</xsl:template>

Or, another approach, you can add the namespace

xmlns:ent="http://www.host.com/ERP/Sales/Entities"

to the stylesheet element and add a modified identity template for the ent: elements which changes the namespace of each copied element:

<xsl:template match="ent:*">
  <xsl:element name="ent:{local-name()}" namespace="http://www.host.com/ERP/Sales/Entities">
    <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>

Then your main template could be simplified to

<xsl:template match="/">
    <soapenv:Envelope xmlns="http://www.host.com/ERP/Sales/CustomerOrderManagement"
                      xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                      xmlns:proc="http://www.host.com/ERP/Sales/ProcessPartsOrder"
                      xmlns:ent="http://www.host.com/ERP/Sales/Entities"
                      xmlns:par="http://www.host.com/ERP/Sales/Aggregates/PartsOrder"
                      xmlns:val="http://www.host.com/ERP/Sales/ValueObjects">
      <soapenv:Header/>
      <soapenv:Body>
        <proc:ProcessPartsOrder>
          <proc:MessageHeader>
            <xsl:apply-templates select="/proc:ProcessPartsOrder/proc:MessageHeader/ent:*"/>
          </proc:MessageHeader>          
        </proc:ProcessPartsOrder>
      </soapenv:Body>
    </soapenv:Envelope>
  </xsl:template>
</xsl:stylesheet>

To also copy attributes, add an unmodifed identity template.

Upvotes: 2

Related Questions