function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Maf_007Maf_007 

DOM Parsing Issue

Hi All I am trying to parse an XML string using DOM parser and got stuck. Is there anyone who can give me some insight on this:

Below is the XML string I am trying to Parse:

String XmlResponse = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> '+
   						' <soap:Body>'+
      					'<GetInventoryDetailsResponse xmlns="http://services.XXXXXXX.com/schema/bs/inventory/v01/MaintainInventory" xmlns:ns2="http://services.XXXXXXX.com/schema/common/header/v01/Header" xmlns:ns3="http://services.XXXXXXX.com/schema/common/inventory/v01/inventory" xmlns:ns4="http://services.XXXXXXX.com/schema/common/acknowledgement/v01/Acknowledgement"> '+
      					'<Inventory>'+
   						'<ns3:TypeDesignator>test</ns3:TypeDesignator>'+
   						'<ns3:TypeDescription>test123</ns3:TypeDescription>'+
      					'</Inventory>'+
   						'</GetInventoryDetailsResponse>'+
						'</soap:Body>'+
        				'</soap:Envelope>';

And my Code is Below:

public static final String soapNS = 'http://schemas.xmlsoap.org/soap/envelope/';
public static final String Acknowledgement_ns = 'http://services.xxxx.com/schema/common/acknowledgement/v01/Acknowledgement';
public static final String MaintainInv_ns = 'http://services.xxxx.com/schema/bs/Inventory/v01/MaintainInventory';
public static final String Inv_ns = 'http://services.xxxx.com/schema/common/Inventory/v01/Inventory';
public static final String Head_ns = 'http://services.xxxx.com/schema/common/header/v01/Header';

Dom.Document doc = new Dom.Document();
doc.load(XmlResponse);

dom.XmlNode xroot = doc.getrootelement();
String body_prefix = xroot.getPrefixFor(soapNS);
			
System.debug('Body Prefix is: ----------------'+body_prefix);
			
dom.XmlNode body = xroot.getChildElement('Body', soapNS);
			
System.debug('Body is: ---------------->>>'+body);

dom.XmlNode Invres = body.getChildElement('GetInventoryDetailsResponse', null);

System.debug(Invres is: ---------------->>>'+Invres);

//Above Line I get null Value but it should have inventory node under it???

tried with following still same issue:

//dom.XmlNode Invres = body.getChildElement('GetInventoryDetailsResponse', MaintainInventory_ns+' '+Inventory_ns+' '+Head_ns+' '+Acknowledgement_ns);

Any Idea what is wrong there?


Best Answer chosen by Maf_007
Maf_007Maf_007
Hi Sunny,

Thanks for your reply. Your example is somewhat different than what I have asked. You posted an example of how to parse an xml based on user input on visualforce page and show the output. This will surely not work with node with namespaces which is my issue. 

After debugging the problem in detail I have found the solution and given below if anyone encounter the same problem:


dom.XmlNode body = xroot.getChildElement('Body', soapNS);
System.debug('Body is: ---------------->>>'+body);

The above debug established the namespace for <GetInventoryDetailsResponse> is following: 

xmlns="http://services.XXXXXXX.com/schema/bs/inventory/v01/MaintainInventory"

Therefore, replacing my namespace in getChildElement(node, namespace) did the trick. And the correct namespace is below:

dom.XmlNode Invres = body.getChildElement('GetInventoryDetailsResponse', MaintainInv_ns);

System.debug(Invres is: ---------------->>>'+Invres);

Instead of: 

dom.XmlNode Invres = body.getChildElement('GetInventoryDetailsResponse', null);


This brought the correct node and was able to parse the response.

Thanks for your time looking at the issue.

All Answers

sunny522sunny522
Hi MAF_007,
   Go through the example below.

Apex class:

public  class Xmlparsar
{
    //xml string
    public String xmlstring{get;set;}
  
    //display xml string
    public String outxmlstring{get;set;}
  
    //rootelement
    public String rootElement{get;set;}
  
    //
    public String filename{get;set;}
  
    public blob body{get;set;}
     
    //constructor
    public Xmlparsar()
    {
   
    }
  
   
//Parsing xml what you entered in the left text area
    public pagereference Parsexml()
    {
       DOM.Document xmlDOC = new DOM.Document();
       xmlDOC.load(xmlstring);
       DOM.XMLNode rootElement = xmlDOC.getRootElement();
       outxmlstring=String.valueof(xmlDOC.getRootElement().getName());
       for(DOM.XMLNode xmlnodeobj:xmlDOC.getRootElement().getChildElements())
       //.getChildren())
       {       
        
        
          loadChilds(xmlnodeobj);        
       }     
       return null;
    }
  
    //loading the child elements
    public void loadChilds(DOM.XMLNode xmlnode)
    {
        for(Dom.XMLNode child : xmlnode.getChildElements())
        {
          if(child.getText()!= null)
          {
          outxmlstring+='\n'+child.getName()+': '+child.getText();
      
          }
          loadChilds(child);      
        }
    }
  
  
//This is for parsing xml file what you selected
  public pagereference Parsexmlfile()
  {
       DOM.Document xmlDOC = new DOM.Document();
       xmlstring=body.tostring();        
       xmlDOC.load(xmlstring);
       DOM.XMLNode rootElement = xmlDOC.getRootElement();
       outxmlstring=String.valueof(xmlDOC.getRootElement().getName());//gives you root element Name
       for(DOM.XMLNode xmlnodeobj:xmlDOC.getRootElement().getChildElements())
       {       
                 
          loadChilds(xmlnodeobj);
       }     
      return null;
    }
}

visualforce page :

<apex:page Controller="Xmlparsar">

<apex:form >
        <apex:pageBlock >
            <apex:pageBlockButtons location="bottom">
                <apex:commandButton value="Parse Xml" action="{!Parsexml}" />  
                <apex:commandButton value="ParseXML File" action="{!Parsexmlfile}"/>
            </apex:pageBlockButtons>
            <apex:inputTextArea value="{!xmlstring}" style="width:336px;height:260px;"/> &nbsp;&nbsp;
            <apex:inputTextArea value="{!outxmlstring}" style="width:336px;height:260px;" id="response"/><br/>

            <apex:outputLabel value="Select Xml File" for="file"/>
            <apex:inputFile fileName="{!fileName}" value="{!body}"/>
        </apex:pageBlock>
    </apex:form>
  
</apex:page>

if this provides you with useful information and if this is what you where looking for then please mark it as a solution for other benefits.
Maf_007Maf_007
Hi Sunny,

Thanks for your reply. Your example is somewhat different than what I have asked. You posted an example of how to parse an xml based on user input on visualforce page and show the output. This will surely not work with node with namespaces which is my issue. 

After debugging the problem in detail I have found the solution and given below if anyone encounter the same problem:


dom.XmlNode body = xroot.getChildElement('Body', soapNS);
System.debug('Body is: ---------------->>>'+body);

The above debug established the namespace for <GetInventoryDetailsResponse> is following: 

xmlns="http://services.XXXXXXX.com/schema/bs/inventory/v01/MaintainInventory"

Therefore, replacing my namespace in getChildElement(node, namespace) did the trick. And the correct namespace is below:

dom.XmlNode Invres = body.getChildElement('GetInventoryDetailsResponse', MaintainInv_ns);

System.debug(Invres is: ---------------->>>'+Invres);

Instead of: 

dom.XmlNode Invres = body.getChildElement('GetInventoryDetailsResponse', null);


This brought the correct node and was able to parse the response.

Thanks for your time looking at the issue.

This was selected as the best answer