how to parse the xml inside CDATA of another xml using xslt?

Shankar picture Shankar · Jan 24, 2013 · Viewed 8.7k times · Source

I need to transform the XML inside the CDATA of the XML using the single XSLT.

I have an XML as below with xml inside the CDATA as in the below xml.

    <message channel-id="e01db0aa-b3db-4b6c-a055-7a0d5c1d1f20" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
    <send-parameters>
               <agent-parameter multi-valued="false">
                 <name>Networks</name>
                 <value><![CDATA[<Networks>
    <Network>
      <GroupCode>EXTPRI</GroupCode>
      <NetworkTypeId>LANI</NetworkTypeId>   
      <OrgNetworkPlatformName>EON-0cbu0cust12301dcd-D-PCL-0002</OrgNetworkPlatformName>
      <OrgNetworkPlatformID>urn:vcloud:network:b7ccfd5f-cfd7-48eb-9dd6-1989b08d7b86</OrgNetworkPlatformID>
      </Network>
      <Network>
      <GroupCode>EXTPRI</GroupCode>
      <NetworkTypeId>LANI</NetworkTypeId>   
      <OrgNetworkPlatformName>ABC-0cbu0cust12301dcd-D-PCL-XYZ</OrgNetworkPlatformName>
      <OrgNetworkPlatformID>urn:vcloud:network:b7ccfd5f-cfd7-48eb-9dd6-1989b08d7b86</OrgNetworkPlatformID>
    </Network>

    </Networks>]]></value>
               </agent-parameter>

                        </send-parameters>
          </message>

I need to transform the xml into :

    <?xml version="1.0" encoding="UTF-8"?>
    <message xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" channel-id="7652d759-4b32-44d4-8a27-9e390f0cae7b">
        <send-parameters>
            <agent-parameter multi-valued="false">
                <name>ExternalPublicOrgNWPlatformID_DDC</name>
                <value>EON-0cbu0cust12301dcd-D-PCL-0002</value>
            </agent-parameter>
                    <agent-parameter multi-valued="false">
                <name>ExternalPublicOrgNWPlatformID_DS</name>
                <value>ABC-0cbu0cust12301dcd-D-PCL-XYZ</value>
            </agent-parameter>
        </send-parameters>
    </message>

This is the sample output I have given there would be multiple nodes inside the xml that i need to traverse through and generate the output xml.

I am using the xslt by directing the xpath upto the node inside the cdata of the source xml. but it is giving empty as it was not in a tree structure format.

I can not get the X-Path for the xml inside the CDATA. It is working well if I remove CDATA in the xml , but the xml is comming from the external system which can not be modified.

I can't use multiple xslts I need to apply single XSLT.

Could you please suggest me on this.

Many thanks in anticipation..

Answer

Michael Kay picture Michael Kay · Jan 25, 2013

CDATA means "character data", and it is properly used to indicate that the contained text does not contain any markup. If it is misused to wrap text that does contain markup, your only answer is to extract the textual content and put it through a second phase of parsing. XSLT 1.0 and 2.0 do not contain a function that allows you to parse lexical XML, but XSLT 3.0 does. If you're stuck with XSLT 1.0, you'll have to write your own extension function that passes the data to a parser and gets the root of the resulting node tree back.