7

I am having difficulty parsing the XML returned from a webservice callout. In the past, I've always been able to use XMLstreamreader, but it does not seem to work with formatting of the XML from this vendor (FedEx). Rather than having elements with attributes like this:

  <book title="Salesforce.com for Dummies"> -- where book is the element and title is the attribute

the XML has child objects who have child objects and so on. The above example would like this:

  <book>
    <title>Salesforce.com for Dummies</title>
  </book>

The actual XML is below (Fedex). I need to pull out the ServiceType and TotalNetCharge > Amount (note: there are other child objects using Amount as element name).

  <RateReplyDetails>
    <ServiceType>FIRST_OVERNIGHT</ServiceType>
    <RatedShipmentDetails>
      <ShipmentRateDetail>
        <TotalNetCharge>
          <Currency>USD</Currency>
          <Amount>55.61</Amount>
        </TotalNetCharge>
      </ShipmentRateDetail>
    </RatedShipmentDetails>
  </RateReplyDetails>

I've taken a look at parsing XML with the DOM parser, but can't seem to make the shift from documentation to returning the values. If someone could provide a real working example, I would be grateful.

Thanks, KMT

2 Answers 2

5

This should help get you started:

String testxml = '<?xml version="1.0" encoding="UTF-8"?>' +
    '<RateReplyDetails>' +
    '<ServiceType>FIRST_OVERNIGHT</ServiceType>' +
    '<RatedShipmentDetails>' +
    '  <ShipmentRateDetail>' +
    '    <TotalNetCharge>' +
    '      <Currency>USD</Currency>' +
    '      <Amount>55.61</Amount>' +
    '    </TotalNetCharge>' +
    '  </ShipmentRateDetail>' +
    '</RatedShipmentDetails>' +
  ' </RateReplyDetails>';

     Dom.Document docx = new Dom.Document();
     docx.load(testxml);

dom.XmlNode xroot = docx.getrootelement() ;
String Service = xroot.getChildElement('ServiceType', null).getText();
system.debug(Service);

dom.XmlNode xrCharge = xroot.getChildElement('RatedShipmentDetails', null)
    .getChildElement('ShipmentRateDetail', null)
    .getChildElement('TotalNetCharge', null);

String sCurrency = xrCharge.getChildElement('Currency', null).gettext();
String sAmount = xrCharge.getChildElement('Amount', null).gettext();
system.debug(sCurrency + ':' + sAmount);
2
  • Thank you -- this really gave me a visual of what I needed to do. I used a combo of this and Keith C's answer below to get everything up and running!
    – KMT333
    Nov 8, 2013 at 21:09
  • 1
    its looking like hard coded class.
    – KS Kumaar
    Aug 30, 2016 at 11:00
5

Below is a real working example of a DOM parser (obviously not for your XML) where the XML is all elements and not attributes. Note that it is not at all tolerant of missing elements. It illustrates the commonly used methods. If your XML has no namespaces defined, supply null for the namespace method arguments.

public class MedicalCodeSearchRequestResponseParser {

    private static final String SE = 'http://www.w3.org/2003/05/soap-envelope';
    private static final String TE = 'http://tempuri.org/';
    private static final String MD = 'http://MDGuidelines.WebService';

    public class Result {
        public String CodeSetType {get; set;}
        public String MedicalCodeDiagnosticCategory {get; set;}
        public String MedicalCodeValue {get; set;}
        public String MedicalCodeDescription {get; set;}
    }

    public List<Result> parse(Dom.Document response) {
        Results results = new List<Result>();
        Dom.XMLNode codes = response
                .getRootElement()
                .getChildElement('Body', SE)
                .getChildElement('MedicalCodeSearchRequestResponse', TE)
                .getChildElement('MedicalCodeSearchRequestResult', TE)
                .getChildElement('CodeSetElement', MD);
        for (Dom.XMLNode child1 : codes.getChildElements()) {
            if (matches(child1, 'MedicalCodesResultSetElement', MD)) {
                Dom.XMLNode code = child1.getChildElement(
                        'MedicalCodeResultSetElement', MD);
                for (Dom.XMLNode child2 : code.getChildElements()) {
                    if (matches(child2, 'MedicalCodeElement', MD)) {
                        Result r = new Result();
                        r.CodeSetType = child1.getChildElement(
                                'CodeSetType', MD).getText();
                        r.MedicalCodeDiagnosticCategory = child2.getChildElement(
                                'MedicalCodeDiagnosticCategory', MD).getText();
                        r.MedicalCodeValue = child2.getChildElement(
                                'MedicalCodeValue', MD).getText();
                        r.MedicalCodeDescription = child2.getChildElement(
                                'MedicalCodeDescription', MD).getText();
                        results.add(r);
                    }
                }
            }
        }
        return results;
    }
    private Boolean matches(Dom.XMLNode node, String name, String namespace) {
        return node.getName() == name && node.getNamespace() == namespace;
    }
}
2
  • Thank you -- I needed this to sort out how to drill down through 7 levels of XML to get to the items I needed using BritishBoyinDCs help above.
    – KMT333
    Nov 8, 2013 at 21:10
  • This very helpful in understanding Dom parser.
    – Pam
    Feb 28, 2015 at 7:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .