[SalesForce] Error converting HttpResponse to Dom.Document

I am calling the Tooling API from Apex in order to find out if a Custom Field has been created. Here is my code:

        HttpRequest req = new HttpRequest();
        req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
        req.setHeader('Content-Type', 'application/json');

        req.setEndpoint(Utils.GetBaseUrlForInstance()+'/services/data/v30.0/tooling/query/?q=Select+Id+from+CustomField+where+DeveloperName=\''+objAndField[1]+'\'+and+TableEnumOrId=\''+objAndField[0]+'\'');
        req.setMethod('GET');

        Http h = new Http();
        HttpResponse res = h.send(req);
        System.debug(res.getBody());
        Dom.Document doc = res.getBodyDocument();
        Dom.XMLNode xmlNode = doc.getRootElement();
        Integer totalSize = Integer.valueOf(xmlNode.getChildElement('totalSize', null).getText());          
        return totalSize > 0;

And here is the log. You can see that the request succeeds and finds the CustomField but it chokes on converting it to a Dom.Document

19:05:55.047 (47524557)|CALLOUT_REQUEST|[793]|System.HttpRequest[Endpoint=https://na24.salesforce.com/services/data/v30.0/tooling/query/?q=Select+Id+from+CustomField+where+DeveloperName='sososo'+and+TableEnumOrId='Account', Method=GET]
19:05:55.192 (192996453)|CALLOUT_RESPONSE|[793]|System.HttpResponse[Status=OK, StatusCode=200]
19:05:55.193 (193056935)|SYSTEM_METHOD_EXIT|[793]|System.Http.send(ANY)
19:05:55.193 (193102469)|SYSTEM_METHOD_ENTRY|[794]|System.HttpResponse.getBody()
19:05:55.193 (193204909)|SYSTEM_METHOD_EXIT|[794]|System.HttpResponse.getBody()
19:05:55.193 (193248897)|SYSTEM_METHOD_ENTRY|[794]|System.debug(ANY)
19:05:55.193 (193265508)|USER_DEBUG|[794]|DEBUG|{"size":1,"totalSize":1,"done":true,"queryLocator":null,"entityTypeName":"CustomFieldDefinition","records":[{"attributes":{"type":"CustomField","url":"/services/data/v30.0/tooling/sobjects/CustomField/00N1a000002n3ETEAY"},"Id":"00N1a000002n3ETEAY"}]}
19:05:55.193 (193278096)|SYSTEM_METHOD_EXIT|[794]|System.debug(ANY)
19:05:55.193 (193295673)|SYSTEM_METHOD_ENTRY|[795]|System.HttpResponse.getBodyDocument()
19:05:55.193 (193517647)|EXCEPTION_THROWN|[795]|System.XmlException: only whitespace content allowed before start tag and not { (position: START_DOCUMENT seen {… @1:1)
19:05:55.193 (193612605)|SYSTEM_METHOD_EXIT|[795]|System.HttpResponse.getBodyDocument()
19:05:55.193 (193638491)|SYSTEM_MODE_EXIT|false
19:05:55.193 (193735001)|FATAL_ERROR|System.XmlException: only whitespace content allowed before start tag and not { (position: START_DOCUMENT seen {… @1:1)

I basically want to check that totalSize in the response is equal to 1. If it makes any difference, I'm calling the Tooling API from a @RemoteAction.

Best Answer

The REST API version of the Tooling API is returning JSON by default where you are trying to read it into an XML document.

You could either tell the REST API that you want XML in the response (Accept request header) or process the response as JSON.

It's a bit raw, but here is a JSON version.

HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
req.setHeader('Accept', 'application/json');

string fieldName = 'CustomerPriority';
string tableName = 'Account';

req.setEndpoint('https://'+System.URL.getSalesforceBaseUrl().getHost()+'/services/data/v30.0/tooling/query/?q=Select+Id+from+CustomField+where+DeveloperName=\''+fieldName+'\'+and+TableEnumOrId=\''+tableName+'\'');
req.setMethod('GET');

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

JSONParser parser = JSON.createParser(res.getBody());
integer totalSize = 0;
while (parser.nextToken() != null) {
    if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) && (parser.getText() == 'totalSize')) {

        parser.nextToken();

        totalSize += parser.getIntegerValue();
        break;
    }
}
System.debug(totalSize);
Related Topic