Recipes by Category

App Distribution (2) Bundle logic, interface and services for distribution. App Logic (37) The Apex programming language, workflow and formulas for logic. Collaboration (6) The Salesforce Chatter collaboration platform. Database (29) Data persistence, reporting and analytics. Integration (33) Web Service APIs and toolkits for integration. Security (9) Platform, application and data security. Tools (4) Force.com tooling User Interface (36) Visualforce MVC and metadata-drive user interfaces. Web Sites (12) Public web sites and apps with optional user registration and login.
Beta Feedback
Cookbook Home » Parsing XML using the Apex DOM Parser

Parsing XML using the Apex DOM Parser

Post by Jon Mountjoy  (2011-02-02)

Status: Unverified
Level: novice

Problem

You want to parse some XML using the native Apex DOM parser. You want your program to display attributes, as well as iterate through any child nodes.

Solution

This code sample demonstrates how to set up a simple test environment - it's a Visualforce page with two text areas. You can enter your XML in the one text area, click "Parse", and see a linear result of the parse in the right text area.

Using this code, you can experiment with the parser and the different text that you want to parse.

  1. Create an Apex class called ParseTest . Use the code ParseText ZIP file referenced below. The rest of this document provides a walk through of the main parts of the code, as well as a Visualforce page that can utilise it.

    The following method checks that you're actually parsing XML. Almost all XML parsing works like this. You construct a new Document instance, and in this case use its load() method to parse a String. If something goes wrong, a System.XMLException is thrown.

        private String parse(String toParse) {
          DOM.Document doc = new DOM.Document();      
          try {
            doc.load(toParse);    
            DOM.XMLNode root = doc.getRootElement();
            return walkThrough(root);
            
          } catch (System.XMLException e) {  // invalid XML
            return e.getMessage();
          }
        }
     

    The important DOM.XMLNode class is the type of every node in the parsed XML. Here we call getRootElement() to returned the root element of the parsed XML, and assign it to an instance of this class. At this point you have a parsed document. Simply walk through the parse tree by walking by accessing the nodes. The above code calls walkThrough() to do this. Here's the code:

        private String walkThrough(DOM.XMLNode node) {
          String result = '\n';
          if (node.getNodeType() == DOM.XMLNodeType.COMMENT) {
            return 'Comment (' +  node.getText() + ')';
          }
          if (node.getNodeType() == DOM.XMLNodeType.TEXT) {
            return 'Text (' + node.getText() + ')';
          }
          if (node.getNodeType() == DOM.XMLNodeType.ELEMENT) {
            result += 'Element: ' + node.getName();
            if (node.getText().trim() != '') {
              result += ', text=' + node.getText().trim();
            }
            if (node.getAttributeCount() > 0) { 
              for (Integer i = 0; i< node.getAttributeCount(); i++ ) {
                result += ', attribute #' + i + ':' + node.getAttributeKeyAt(i) + '=' + node.getAttributeValue(node.getAttributeKeyAt(i), node.getAttributeKeyNsAt(i));
              }  
            }
            for (Dom.XMLNode child: node.getChildElements()) {
              result += walkThrough(child);
            }
            return result;
          }
          return '';  //should never reach here 
        }
    
    This code makes use of a lot of methods on the XMLNode class to access and recurse through the parsed XML:
    • getNodeType() returns the type of the node, which will either be a comment, a text node, or an element. The element type is the most important.
    • getName() returns the name of the element you're currently looking at. For example, if your node represents the XML <foobar> then the name will be "foobar".
    • getText() returns the text within the node. This is often filled with whitespace - which is why I use trim().
    • getAttributeCount() tells you how many attributes there are on the node.
    • getAttributeKeyAt(n) and getAttributeKeyNsAt(n) tell you the name and namespace of the nth attribute.
    • getAttributeValue() returns the value of a given attribute, given its key and namespace.
    • getChildElements() returns the child elements of the node, if there are any.

    That should be enough for you to walk through any parsed XML.

  2. Create a Visualforce page that uses this controller. Here's a simple one with two fields:
    <apex:page controller="ParseTest" sidebar="false" showHeader="false" >
      
       <apex:form>
         <apex:inputtextarea cols="40" rows="20" value="{!textToParse}"  />
         <apex:inputtextarea cols="40" rows="20" id="result" value="{!parsedText}"/>     
         <br />
         <apex:commandButton value="Parse" action="{!parse}" reRender="result"/>
    
       </apex:form>
    
    </apex:page>
    
    The left text area contains the XML to be parsed. When you click the button, the parser does its job, eventually calling the walkThrough() method above - the results are displayed in the right text area. Here's a look at it in action.
    You can access the online demo by clicking the Demo link above.

Discussion

Note:

  • I haven't found the COMMENT and TEXT node types to ever appear. I don't know why.
  • The HTTP response object, used when making something like an HTTP GET request, provides a getBodyDocument() that returns the parsed XML of the body. For example:
      
      HTTPResponse res = h.send(req);
      DOM.Document doc = res.getBodyDocument();
    

Resource files:

ParseTest

Share

Recipe Activity - Please Log in to write a comment

Hi Jon,

        I placed my xml file in Document object and now I want to parse that  xml file placed in Document object.How to access that file here to parse.By using load() or any other way to access that file

by Sreenivasa Rao Mariyavula  (2013-10-07)

Awesome..!!
Thanks..

by Chandan Panigrahy  (2012-04-27)

Simple yet important . Thanks!

by abhineet majrikar  (2011-11-27)

 Very useful recipe. Thanks Jon!

by Ping Pong  (2011-04-12)

I sent some enhancements, but not sure if they were posted. Please let me know if you received them. Thanks!

voted as verified by sgkmills  (2011-03-10)

Awesome recipe! Thanks Jon!

voted as verified by Butters  (2011-02-13)

X

Vote to Verify a Recipe

Verifying a recipe is a way to give feedback to others and broaden your own understanding of the capabilities on Force.com. When you verify a recipe, please make sure the code runs, and the functionality solves the articulated problem as expected.

Please make sure:
  • All the necessary pieces are mentioned
  • You have tested the recipe in practice
  • Have sent any suggestions for improvements to the author

Please Log in to verify a recipe

You have voted to verify this recipe.