simplexml_load_string not creating an object - php

My XML is:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<FindOrders xmlns="http://www.JOI.com/schemas/ViaSub.WMS/">
<orders>
<order>
<MarkForName />
<BatchOrderID />
<CreationDate>2013-08-09T17:41:00</CreationDate>
<EarliestShipDate />
<ShipCancelDate />
<PickupDate />
<Carrier>USPS</Carrier>
<BillingCode>Prepaid</BillingCode>
<TotWeight>0.00</TotWeight>
<TotCuFt>0.00</TotCuFt>
<TotPackages>1.0000</TotPackages>
<TotOrdQty>1.0000</TotOrdQty>
<TotLines>1.00</TotLines>
<Notes />
<OverAllocated />
<PickTicketPrintDate />
<ProcessDate />
<TrackingNumber />
<LoadNumber />
<BillOfLading />
<MasterBillOfLading />
<ASNSentDate />
<ConfirmASNSentDate />
<RememberRowInfo>398879:12:2:::0:False</RememberRowInfo>
</order>
</orders>
</FindOrders>
<totalOrders xmlns="http://www.JOI.com/schemas/ViaSub.WMS/">1</totalOrders>
</soap:Body>
</soap:Envelope>
When I do:
$a = simplexml_load_string($str);
print_r($a);
I get: SimpleXMLElement Object ( ) instead of an object with all of those parameters. Why is this?

You are missing the namespace declaration (php manual) for SOAP
$a = simplexml_load_string($str);
$a->registerXPathNamespace('soap', 'http://www.w3.org/2003/05/soap-envelope');
$result = $a->xpath('//soap:Body');
print_r($result);
Result (preview)
Array
(
[0] => SimpleXMLElement Object
(
[FindOrders] => SimpleXMLElement Object
(
[orders] => SimpleXMLElement Object
(
[order] => SimpleXMLElement Object
...
...

I'm guessing when you say you want to see an object with all those parameters, you're looking to output the xml document you just created.
Looking at the documentation at http://www.php.net/manual/en/simplexmlelement.asxml.php, here's what you need to do:
echo $a->asXML();

My case was dealing with soap response. I have to parse and clean it first before converting it to array.
$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $xml); // remove all colons and unnecessary characters.
$xml = new SimpleXMLElement($response);
$body = $xml->xpath('//sBody'); // should refer to soap body element like soapbody, sbody, etc..
$array = json_decode(json_encode((array)$body), TRUE);

Related

How to get value of XML tag (which contains namespace) using PHP's simplexml_load_string?

How do I get the value of "TagOne" (i.e. foo) and TagTwo (i.e. bar) from the XML below using
simplexml_load_string? I'm stumped by the namespace called "ns" in the tag.
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Body>
<ns:ExampleInterface_Output xmlns:ns="http://example.com/interfaces">
<ns:TagOne>Foo</ns:TagOne>
<ns:TagTwo>Bar</ns:TagTwo>
</ns:ExampleInterface_Output>
</SOAP-ENV:Body>
Thanks very much for your kind help!
Check this code:
<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns:ExampleInterface_Output xmlns:ns="http://example.com/interfaces">
<ns:TagOne>Foo</ns:TagOne>
<ns:TagTwo>Bar</ns:TagTwo>
</ns:ExampleInterface_Output>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XML;
$xse = new SimpleXMLElement($xml);
$exampleInterface = $xse
->children('SOAP-ENV', true)
->children('ns', true);
foreach ($exampleInterface->children('ns', true) as $key => $value) {
//Do your stuff
}
Well you can declare the "ns" namespace to simplexml_load_string like this:
$xml = simplexml_load_string($string, "SimpleXMLElement", 0, "ns", TRUE);
This says that "ns" is a namespace prefix (rather than a namespace URL). See the PHP doc page for simplexml_load_string for more details.
Another problem is that the Body element has a "SOAP-ENV" prefix which is not declared anywhere in the XML, so you will get a warning about this. However, the value of $xml will become an object structured like this:
SimpleXMLElement Object (
[ExampleInterface_Output] => SimpleXMLElement Object (
[TagOne] => Foo
[TagTwo] => Bar
)
)
But, warning aside, this might be exactly what you need. If the warning is a problem, you can simply remove the "SOAP-ENV" prefix from the start and end tags of the Body element.

Parse SOAP response with PHP/xpath - Cant step further than one node

I've tried to read other tutorials & SO responses on this but I just can't seem to make it work :/
I'm able to make the SOAP request and get a response but I can't seem to parse the response.
$result = $client->GetAllAttributes($params);
And the resulting response xml is:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetAllAttributesResponse xmlns="http://connect2.askadmissions.net/webservices/">
<GetAllAttributesResult>
<result>
<code>1</code>
<ErrorMessage />
<returndata>
<attributes>
<attribute>
<type>attribute</type>
<level />
<name>text1321</name>
<mappingname><![CDATA[Extra-Curricular Interest]]></mappingname>
<datatype>Varchar2</datatype>
<size>35</size>
<validationexp />
</attribute>
<attribute> (same as above, several of these are returned</attribute>
</attributes>
</returndata>
</result>
</GetAllAttributesResult>
</GetAllAttributesResponse>
</soap:Body>
</soap:Envelope>
</xml>
I've tried
$xml = simplexml_load_string($client->__getLastResponse());
print_r($xml);
But it just prints "SimpleXMLElement Object ( ) "
I've tried
$responseXML = $client->__getLastResponse();
$xml = simplexml_load_string($responseXML);
$xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('hob', 'http://connect2.askadmissions.net/webservices/');
$item = $xml->xpath('//hob:GetAllAttributesResult');
print_r($item);
and I get an array
Array
(
[0] => SimpleXMLElement Object
(
[0] => <result><code>1</code><ErrorMessage /><returndata><attributes><attribute> <type>attribute</type><level />
etc. (array is very long)
My problem comes when I try to step further into the tree. If I do
$item = $xml->xpath('//hob:GetAllAttributesResult/hob:result');
or
$item = $xml->xpath('//hob:GetAllAttributesResult/hob:code');
I end up with an empty array.
How do I step further into the tree?
Thank you very much for any help.
To access the element's value, you need to access the first element of the array. And you may need to cast it to string to get the string value
e.g. in your example you can do:
$item = $xml->xpath('//hob:GetAllAttributesResult/hob:result/hob:code');
print_r((string)$item[0]);

PHP - parsing complicated XML with NameSpaces

I'm guessing the NameSpaces are causing simplexml_load_string to not work, but I'm definitely not sure.
log.xml
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sns="http://soap.com/pbx">
<env:Body>
<sns:CDR>
<PrimaryCallID>02v7b7c16v#12.123.123.12</PrimaryCallID>
<CallID>d352f920#pbx</CallID>
<From>"SMITH JOHN " <sip:11234567890#sub.domain.com:5060;user=phone></From>
<To><sip:3216549870#111.111.111.111:5060;user=phone></To>
<Direction>O</Direction>
<Type>attendant</Type>
<RemoteParty />
<LocalParty />
<TrunkName />
... more xml...
</sns:CDR>
</env:Body>
</env:Envelope>
parse.php
<?php
$string = "log.xml";
$xml = simplexml_load_string($string);
print_r($xml);
?>
I'm getting nothing back from the print_r
What am I missing?
simplexml_load_string takes a string as an argument not a filename.
you're trying to load the string "log.xml" as a XML and that doesn't work
you can use this intead:
$filename = "log.xml";
$xml = simplexml_load_string(file_get_contents($filename));
print_r($xml);

PHP ODATA XML parsing with SimpleXMLElement

I have the following being returned as XML from source:
<content type="application/xml">
<m:properties>
<d:ID>30</d:ID>
<d:Name></d:Name>
<d:ProfileImageUrl>default.png</d:ProfileImageUrl>
<d:ThumbnailUrl>default.png</d:ThumbnailUrl>
<d:FavoriteCount m:type="Edm.Int64">0</d:FavoriteCount>
<d:ViewCount m:type="Edm.Int64">12030</d:ViewCount>
<d:LastMonthViewCount m:type="Edm.Int64">1104</d:LastMonthViewCount>
<d:LastWeekViewCount m:type="Edm.Int64">250</d:LastWeekViewCount>
<d:LastDayViewCount m:type="Edm.Int64">21</d:LastDayViewCount>
<d:CreationDate m:type="Edm.DateTime">2011-03-28T13:46:54.227</d:CreationDate>
<d:Enabled m:type="Edm.Boolean">true</d:Enabled>
<d:UrlSafeName>t-boz</d:UrlSafeName>
<d:LastDayFavoriteCount m:type="Edm.Int64">0</d:LastDayFavoriteCount>
<d:LastWeekFavoriteCount m:type="Edm.Int64">0</d:LastWeekFavoriteCount>
<d:LastMonthFavoriteCount m:type="Edm.Int64">0</d:LastMonthFavoriteCount>
<d:IsOnTour m:type="Edm.Boolean">false</d:IsOnTour>
<d:TodayRank m:type="Edm.Int32">6272</d:TodayRank>
<d:WeekRank m:type="Edm.Int32">6851</d:WeekRank>
<d:MonthRank m:type="Edm.Int32">6915</d:MonthRank>
<d:AllTimeRank m:type="Edm.Int32">7973</d:AllTimeRank>
</m:properties>
</content>
I am retrieving this via file_get_contents then creating via SIMPLEXMLElement. However I am unable to access the content->properties fields (ie. ID, Name, ProfileImageUrl, etc). All I see from the SIMPLEXMLElement is the following:
[content] => SimpleXMLElement Object ( [#attributes] => Array ( [type] => application/xml ) )
Any thoughts on how I get this data?
Thanks!
Accessing namespaced elements is easy with SimpleXML, you just tell the children() method which namespace to look in.
A super basic example would look like:
$xml = <<<XML
<content type="application/xml" xmlns:m="urn:m" xmlns:d="urn:d">
<m:properties>
<d:ID>30</d:ID>
<d:ProfileImageUrl>default.png</d:ProfileImageUrl>
</m:properties>
</content>
XML;
$content = simplexml_load_string($xml);
// Quick way
// $properties = $content->children('m', TRUE)->properties->children('d', TRUE);
// echo $properties->ProfileImageUrl;
// Step by step
$m_elements = $content->children('m', TRUE);
$m_properties = $m_elements->properties;
$d_elements = $m_properties->children('d', TRUE);
echo $d_elements->ProfileImageUrl;

XPath and PHP troubleshooting

I get this error:
Notice: Trying to get property of non-object in
Applies to:
echo $result->Data;
And this output:
Array ()
Background Informations
A function returns a string which contains an XML file.
I want to get some data from two tags and deal with them on their own.
String Data
$data="
<SyncML xmlns='SYNCML:SYNCML1.0'>
<SyncHdr>
</SyncHdr>
<SyncBody>
<betameta>
WANT 1
</betameta>
<Add>
<Data>
WANT 2
</Data>
</Add>
</SyncBody>
</SyncML>";
In the above data, I want values "WANT 1" and "WANT 2"
Code so far
$xml = simplexml_load_string($data);
$result = $xml->xpath("/SyncML/SyncBody");
print_r($result);
echo $result->Data;
$xml->registerXPathNamespace('default','SYNCML:SYNCML1.0');
$result = $xml->xpath("/default:SyncML/default:SyncBody");
Remove the trailing slash.
The only solution I can find is the following:
<?php
$data= <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<SyncML>
<SyncHdr>
</SyncHdr>
<SyncBody>
<betameta>
WANT 1
</betameta>
<Add>
<Data>
WANT 2
</Data>
</Add>
</SyncBody>
</SyncML>
XML;
$xml = simplexml_load_string($data);
$result = $xml->xpath("/SyncML/SyncBody");
print_r($result);
echo $result;
is there anyway you can loose the xmlns?
This will output:
Array
(
[0] => SimpleXMLElement Object
(
[betameta] =>
WANT 1
[Add] => SimpleXMLElement Object
(
[Data] =>
WANT 2
)
)
)

Categories