0

I have tried various methods as seen in here and in here and many more.

I even tried the function in here.

The XML looks something like this:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://tempuri.org/IFooEntryOperation/SaveFooStatusResponse</a:Action></s:Header><s:Body><SaveFooStatusResponse xmlns="http://htempuri.org/"><SaveFooStatusResult xmlns:b="http://schemas.datacontract.org/2004/07/FooAPI.Entities.Foo" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:AWBNumber>999999999</b:AWBNumber><b:IsError>true</b:IsError><b:Status><b:FooEntryStatus><b:StatusCode>Foo_ENTRY_FAILURE</b:StatusCode><b:StatusInformation>InvalidEmployeeCode</b:StatusInformation></b:FooEntryStatus></b:Status></SaveFooStatusResult></SaveFooStatusResponse></s:Body></s:Envelope> 

And here's one example of my code (I have a dozen variations):

$ReturnData = $row["ReturnData"]; // string frm a database if (strpos($ReturnData, "s:Envelope") !== false){ $ReturnXML = new SimpleXMLElement($ReturnData); $xml = simplexml_load_string($ReturnXML); $StatusCode = $xml["b:StatusCode"]; echo "<br>StatusCode: " . $StatusCode; $IsError = $xml["b:IsError"]; echo "<br>IsError: " . $IsError; } 

Another option I tried:

$test = json_decode(json_encode($xml, 1); //this didn't work either 

I either get an empty array or I get errors like:

"Fatal error: Uncaught exception 'Exception' with message 'String could not be parsed as XML"

I have tried so many things, I may lost track of where my code is right now. Please help - I am really stuck...

I also tried:

$ReturnXML = new SimpleXMLElement($ReturnData); foreach( $ReturnXML->children('b', true)->entry as $entries ) { echo (string) 'Summary: ' . simplexml_load_string($entries->StatusCode->children()->asXML(), null, LIBXML_NOCDATA) . "<br />\n"; } 
2
  • You know that pod or b is a namespace, right? Commented Apr 29, 2019 at 7:24
  • @u_mulder yes, I tried declaring a namespace, but that didn't help. Commented Apr 29, 2019 at 7:58

2 Answers 2

1

Method 1.

You can try the below code snippet to parse it an array

$p = xml_parser_create(); xml_parse_into_struct($p, $xml, $values, $indexes);// $xml containing the XML xml_parser_free($p); echo "Index array\n"; print_r($indexes); echo "\nVals array\n"; print_r($values); 

Method 2.

function XMLtoArray($xml) { $previous_value = libxml_use_internal_errors(true); $dom = new DOMDocument('1.0', 'UTF-8'); $dom->preserveWhiteSpace = false; $dom->loadXml($xml); libxml_use_internal_errors($previous_value); if (libxml_get_errors()) { return []; } return DOMtoArray($dom); } function DOMtoArray($root) { $result = array(); if ($root->hasAttributes()) { $attrs = $root->attributes; foreach ($attrs as $attr) { $result['@attributes'][$attr->name] = $attr->value; } } if ($root->hasChildNodes()) { $children = $root->childNodes; if ($children->length == 1) { $child = $children->item(0); if (in_array($child->nodeType,[XML_TEXT_NODE,XML_CDATA_SECTION_NODE])) { $result['_value'] = $child->nodeValue; return count($result) == 1 ? $result['_value'] : $result; } } $groups = array(); foreach ($children as $child) { if (!isset($result[$child->nodeName])) { $result[$child->nodeName] = DOMtoArray($child); } else { if (!isset($groups[$child->nodeName])) { $result[$child->nodeName] = array($result[$child->nodeName]); $groups[$child->nodeName] = 1; } $result[$child->nodeName][] = DOMtoArray($child); } } } return $result; } 

You can get an array using print_r(XMLtoArray($xml));

Sign up to request clarification or add additional context in comments.

1 Comment

Method 1 worked for me and because I like simple and short and I associate that with elegant code (or perhaps because I'm lazy), I didn't go beyond that. Thanx!
1

I don't know how you would do this using SimpleXMLElement but judging by the fact you have tried so many things I trust that the actual method employed is not important so you should therefore find the following, which uses DOMDocument and DOMXPath, of interest.

 /* The SOAP response */ $strxml='<?xml version="1.0" encoding="UTF-8"?> <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"> <s:Header> <a:Action s:mustUnderstand="1">http://tempuri.org/IFooEntryOperation/SaveFooStatusResponse</a:Action> </s:Header> <s:Body> <SaveFooStatusResponse xmlns="http://htempuri.org/"> <SaveFooStatusResult xmlns:b="http://schemas.datacontract.org/2004/07/FooAPI.Entities.Foo" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <b:AWBNumber>999999999</b:AWBNumber> <b:IsError>true</b:IsError> <b:Status> <b:FooEntryStatus> <b:StatusCode>Foo_ENTRY_FAILURE</b:StatusCode> <b:StatusInformation>InvalidEmployeeCode</b:StatusInformation> </b:FooEntryStatus> </b:Status> </SaveFooStatusResult> </SaveFooStatusResponse> </s:Body> </s:Envelope>'; /* create the DOMDocument and manually control errors */ libxml_use_internal_errors( true ); $dom=new DOMDocument; $dom->validateOnParse=true; $dom->recover=true; $dom->strictErrorChecking=true; $dom->loadXML( $strxml ); libxml_clear_errors(); /* Create the XPath object */ $xp=new DOMXPath( $dom ); /* Register the various namespaces found in the XML response */ $xp->registerNamespace('b','http://schemas.datacontract.org/2004/07/FooAPI.Entities.Foo'); $xp->registerNamespace('i','http://www.w3.org/2001/XMLSchema-instance'); $xp->registerNamespace('s','http://www.w3.org/2003/05/soap-envelope'); $xp->registerNamespace('a','http://www.w3.org/2005/08/addressing'); /* make XPath queries for whatever pieces of information you need */ $Action=$xp->query( '//a:Action' )->item(0)->nodeValue; $StatusCode=$xp->query( '//b:StatusCode' )->item(0)->nodeValue; $StatusInformation=$xp->query( '//b:StatusInformation' )->item(0)->nodeValue; printf( "<pre> %s %s %s </pre>", $Action, $StatusCode, $StatusInformation ); 

The output from the above:

 http://tempuri.org/IFooEntryOperation/SaveFooStatusResponse Foo_ENTRY_FAILURE InvalidEmployeeCode 

1 Comment

This looks interesting but I chose Method 1 by @rakesh-jakkar since it is the shortest. Still, you got an upvote. :-)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.