0

I'm calling MetadataAPI as the code below and it's returning getBody() with a very long string as shown below, please scroll horizontal to see it and for brevity purpose I cut short.

HttpRequest req = new HttpRequest();
    req.setMethod( 'POST' );
    req.setHeader( 'Content-Type', 'text/xml; charset=utf-8' );
    req.setHeader( 'SOAPAction', 'readMetadata' );
    req.setEndpoint( URL.getOrgDomainUrl().toExternalForm() + '/services/Soap/m/48.0' );
    req.setBody( soapMessage );

    HttpResponse res = new Http().send( req );
    res.getBody();

Here is the debug output

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/2006/04/metadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><readMetadataResponse><result><records xsi:type=\"Profile\"><fullName>Employee</fullName><applicationVisibilities><application>My_Awesome_App</application><default>false</default><visible>false</visible></applicationVisibilities><applicationVisibilities><application>standard__AppLauncher</application><default>......{removed}..... <objectPermissions><allowCreate>true</allowCreate><allowDelete>false</allowDelete><allowEdit>true</allowEdit><allowRead>true</allowRead><modifyAllRecords>false</modifyAllRecords><object>employee__c</object><viewAllRecords>false</viewAllRecords></objectPermissions>......</soapenv:Body></soapenv:Envelope>

My question is: How to extract the values from <objectPermissions> that getBody() is rendering? or any other attributes. for an example, if I want to read the value of objectPermissions or object how would I go after?

1 Answer 1

1

Generally speaking, you parse it with the XmlNode class:

Dom.Document doc = new Dom.Document();
doc.load(res.getBody());
Dom.XmlNode body = doc.getRootElement().getChildElement('Body','soapenv').getChildElement('readMetadataResponse',null);
for(Dom.XmlNode resultNode: body.getChildElements()) {
  ...
}

This is cumbersome if you want to parse it this way, but it can be done.

You can also use the XmlStreamReader, but I find it more troublesome than even the above, since you also need to build a "state machine".

Finally, you convert the entire mess to an untyped Map, as I demonstrate in my very own XmlToJson parser. It has a convenient "half-way" point where you can get an object that you can then process as if it were a JSON.deserializeUntyped result, which I find incredibly useful (but, be aware that you'll be using inordinate amount of CPU and heap). If you can handle it, and it's rare, this might be useful for you.

Finally, consider researching a REST API alternative. The Metadata API is restricted to System Administrators, while the REST API can be used by almost any user. I make no assumptions as to your use case, but you may want to research this if you haven't already.

2
  • Thank you for your detail response! I'm keep getting the error System.NullPointerException: Attempt to de-reference anull object on this line Dom.XmlNode body = doc.getRootElement().getChildElement('Body','soapenv').getChildElement('readMetadataResponse',null); any pointers how to resolve it?
    – Nick
    May 27, 2020 at 15:21
  • @NickKahn I don't often use XML methods for a reason. You'll need to figure out what the XML is supposed to look like. If you can get a WSDL, that would be even better, since this is clearly a SOAP-based call.
    – sfdcfox
    May 27, 2020 at 15:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.