Options

Parsing XML response from web service in AL

jonathanchyejonathanchye Member Posts: 34
Hi all,

I'm a little new to this so please bear with me.
I have so far managed to make a call to the endpoint however struggling to parse the response.
Below is sample of code I've used to parse send the request:
            Client.DefaultRequestHeaders.Add('AuthToken', AuthToken);      
            if Carrier <> '' then      
                Client.DefaultRequestHeaders.Add('Carrier', Carrier);

            clear(tempBlob);
            clear(lInStream);
            clear(lOutStream);

            tempBlob.Blob.CreateOutStream(lOutStream);
            tempBlob.Blob.CreateInStream(lInStream);
            XMLParServ.Init(Postcode, CountryCode);
            XMLParServ.SetDestination(lOutStream);
            XMLParServ.Export;

            while not lInStream.EOS do begin
                lInStream.ReadText(TextXMLReq);
                TextXMLReqFull := TextXMLReqFull + TextXMLReq;
            end;
    
            Content.WriteFrom(TextXMLReqFull);  

            Client.Post(URLString, Content,Response);

            if not Response.IsSuccessStatusCode then  
                Error(WebServiceErr, Response.HttpStatusCode, Response.ReasonPhrase);

            clear(lInStream);
            Response.Content.ReadAs(TextXMLReqFull);   
            // Response.Content.ReadAs(lInStream);

For some odd reason I get an error response back from the endpoint if I use Response.Content.ReadAs(Instream).
Reading into text variable works and it's acceptable as the value I need in the response is less than 250 characters.

Below is example XML response.
<?xml version="1.0" encoding="UTF-8"?>
<ParcelServiceResponse>
   <Status>Success</Status>
   <Carriers>
      <Carrier Name="ABC" ServiceID="1" ServiceName="24hr" ParcelCost="1.23" Currency="GBP" />
      <Carrier Name="ABC" ServiceID="2" ServiceName="48hr" ParcelCost="2.34" Currency="GBP" />
   </Carriers>
</ParcelServiceResponse>

I've so far managed to parse the Status from response using this code:
            XmlDocument.ReadFrom(lInStream, lXmlDocument);

            if lXmlDocument.SelectSingleNode('//Status', lXmlNode) then
                respStatus := lXmlNode.AsXmlElement.InnerText;

However I can't parse the attribute value (ServiceID and ServiceName). I've tried the below but it won't find the value. I hope someone could kindly advise.
            if lXmlDocument.SelectNodes('//Carriers/Carrier', lXmlNodeList) then begin              

                foreach lCarriersNode in lxmlnodelist do
                begin    
                    if lCarriersNode.SelectSingleNode('ServiceID', lXmlNode) then
                        respServices := respServices +  lXmlNode.AsXmlElement.InnerText;
                end;
            end; 

I've had a look at this webpage (https://community.dynamics.com/nav/b/diveshboramsdnavblog/archive/2018/03/09/vs-code-xml-dom-management-part-2) and tried to use the GetAttribute function but can't seem to get it to work.

Comments

  • Options
    jonathanchyejonathanchye Member Posts: 34
    Well what do you know, tried out something and it worked :)

    for reference I've used this helper function:
        procedure GetAttributeValue(pXMLNode: XmlNode; pAttributeName: Text): Text
        var
            lXmlAttribute: XmlAttribute;
        begin
            if pXMLNode.AsXmlElement().Attributes().Get(pAttributeName, lXmlAttribute) then
                exit(lXmlAttribute.Value());
        end;
    

    Below is how I used the function to get the attribute value:
    
                if lXmlDocument.SelectNodes('//Carriers/Carrier', lXmlNodeList) then begin            
                    foreach lCarriersNode in lxmlnodelist do
                    begin    
                        respServices := respServices + '\' + GetAttributeValue(lCarriersNode, 'ServiceID') + '-' + GetAttributeValue(lCarriersNode, 'ServiceName');
    

    Now I need to figure out why I get a response from endpoint saying "please contact administrator" if I stream the request to the endpoint as below instead of passing the text variable.
                tempBlob.Blob.CreateOutStream(lOutStream);
                tempBlob.Blob.CreateInStream(lInStream);
                XMLParServ.Init(Postcode, CountryCode);
                XMLParServ.SetDestination(lOutStream);
                XMLParServ.Export;
    
    
                while not lInStream.EOS do begin
                    lInStream.ReadText(TextXMLReq);
                    TextXMLReqFull := TextXMLReqFull + TextXMLReq;
                end;
                
                Content.WriteFrom(lInStream);    
                //Content.WriteFrom(TextXMLReqFull); //this works
    
                Client.Post(URLString, Content,Response);
    
                if not Response.IsSuccessStatusCode then  
                    Error(WebServiceErr, Response.HttpStatusCode, Response.ReasonPhrase);
     
                 Response.Content.ReadAs(lInStream);
    
                XmlDocument.ReadFrom(lInStream, lXmlDocument);
    
Sign In or Register to comment.