Can't parse XML using simplexml_load_string in PHP - php

How to pass the following message in PHP?
<?xml version="1.0" encoding="utf-8"?>
<response>
<action>sendmessage</action>
<data>
<acceptreport>
<statuscode>0</statuscode>
<statusmessage>Message accepted for delivery</statusmessage>
<messageid>8abbaf6c-3bdd-4fb7-9c49-282270bbb309</messageid>
<originator>admin</originator>
<recipient>233xxx</recipient>
<messagetype>SMS:TEXT</messagetype>
<messagedata>mdata</messagedata>
</acceptreport>
</data>
</response>
I have tried
$xml = simplexml_load_string($data);
var_dump($xml['data']);
and
var_dump($xml->attributes());
Nothing seems to be working. Any clue? What am I missing?

Try
var_dump($xml->data->acceptreport->messagedata);
$xml->attributes() would be trying to get any attributes on the root node (<response>), and that node has no attributes.

Related

CardDAV get all contacts from iCloud

I try to get all contacts from an iCloud Account...
First I run:
<?xml version="1.0" encoding="UTF-8"?>
<d:propfind xmlns:d="DAV:">
<d:prop>
<d:current-user-principal/>
</d:prop>
</d:propfind>
Then I get /xxxxxxxxxxx/carddavhome/ and run:
<?xml version="1.0" encoding="UTF-8"?>
<d:propfind xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav">
<d:prop>
<card:addressbook-home-set/>
</d:prop>
</d:propfind>
This give me the URL https://pXX-contacts.icloud.com:443/xxxxxxxxxxx/carddavhome/ then I send the following request to this URL:
<?xml version="1.0" encoding="UTF-8"?>
<d:propfind xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav">
<d:prop>
<d:displayname/>
<d:resourcetype/>
</d:prop>
</d:propfind>
And I get:
<?xml version="1.0" encoding="UTF-8"?>
<multistatus xmlns="DAV:">
<response>
<href>/xxxxxxxxxxx/carddavhome/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
<propstat>
<prop>
<displayname/>
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
</multistatus>
If I try to run this to the the URL https://pXX-contacts.icloud.com:443/xxxxxxxxxxx/carddavhome/contacts
<?xml version="1.0" encoding="UTF-8"?>
<card:addressbook-query xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav">
<d:prop>
<d:getetag/>
<card:address-data/>
</d:prop>
</card:addressbook-query>
I get: Improperly formed XML encountered, unexpected root node
What is my mistake? The first 2 queries work and give me the expected results, the 3rd one should give me a list of the addressbooks and groups and the 4th one should give me all VCards.
For the first issue, you did not provide the whole HTTP request but I suspect that you are missing a Depth header with a value of 1:
Depth: 1
For the second issue, there does not seem to be anything wrong with your xml payload. Your url on the other hand seems incorrect as it is at least missing the ending slash that denotes a collection (some *DAV servers are more strict about it). Hopefully, solving the first issue will allow you to use the right url when doing the address-book query.

How to retrieve the first node of a XML after use simplexml_load_string in PHP?

I have the follow xml where the first node is the <Cancellation>
<?xml version='1.0' encoding='UTF-8'?>
<Cancellation>
<version>message-version</version>
<customerID>customer-identifier</customerID>
<invoiceID>invoice-number</invoiceID>
<cancellationDate>yyyy-mm-dd</cancellationDate>
<reason>reason</reason>
<reasonCode>reason-code</reasonCode>
<attempts>attempts-count</attempts>
<merchantID>rocketgate merchant-identifier</merchantID>
<merchantSiteID>site-id</merchantSiteID>
<udf01>user-data</udf01>
</Cancellation>
Eventually I could have a similar xml but for a complete different process like registration, like the follow:
<?xml version='1.0' encoding='UTF-8'?>
<Registration>
<version>message-version</version>
<customerID>customer-identifier</customerID>
<invoiceID>invoice-number</invoiceID>
<merchantID>rocketgate merchant-identifier</merchantID>
<merchantSiteID>site-id</merchantSiteID>
<udf01>user-data</udf01>
</Registration>
I will need to catch this first node in a if condition to redirect to the appropriate path.
Following this link I got an array from the sent xml:
$xmlString = trim(file_get_contents('php://input'));
$xmlObj = simplexml_load_string($xmlString);
$xmlJSON = json_encode($xmlObj);
$xmlArray = json_decode($xmlJSON, true);
But the issue is that I can't see the first <Cancellation> or <Registration> node after passing the xml string to an object.
Even the examples in the php doc is not showing the first node.
I need to test if it is a Cancellation or a Registration. How could I do that?
To find the tag name of the root element in XML just use getName() on the SimpleXMLElement...
echo $xmlObj->getName();

Return a php xpath answer with SOAP

I m trying to return an xpath answer to a soap client (i am using an xml file as database).
The method works fine when it's called on the server side, unfortunatelly, the client always get an annoying " looks like we got no XML document " error, with this kind of
xml answer:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn://localhost/projet/srv" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://xml.apache.org/xml-soap" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:getTypesVehiculeResponse>
<return SOAP-ENC:arrayType="SOAP-ENC:Struct[4]" xsi:type="SOAP-ENC:Array">
<item xsi:type="SOAP-ENC:Struct">
<#attributes xsi:type="ns2:Map">
<item>
<key xsi:type="xsd:string">id</key>
<value xsi:type="xsd:string">0</value>
</item>
...
</return>
</ns1:getTypesVehiculeResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Should I use another way to send my XML database answers than directly return xpath answer?
SoapClient should eliminate the need for xpath querying since it already parses the SOAP XML, but if you still want to use xpath, you can try using simplexml as per this answer. If you have an issue with namespaces, try this

SimpleXml Failed to Generate Object

I am using Soap for web service call and PHP for entire operation. When I send request I get the response as 341025COMPLETE. But when I select it for Source it prints the XML behind it.
We have passed it to simplexml_load_string function but it failed to generate the object for the same.
What will be wrong with simplexml_load_string? When that same string is hard coded it works when it passed through function parameter it failed.
XML that i am getting is :
<applicantscreening xmlns="https://www.example.com/xml/services/PSI"><response><reportid>00000</reportid><backgroundreport></backgroundreport><status>TEST</status></response></applicantscreening>
I think there should be something wrong in xml .
Can you please provide xml string ?
Look at the simple example :
$string = <<<XML
<?xml version='1.0'?>
<document>
<title>Forty What?</title>
<from>Joe</from>
<to>Jane</to>
<body>
I know that's the answer -- but what's the question?
</body>
</document>
XML;
$xml = simplexml_load_string($string);
print_r($xml);

Accessing XML content via PHP using SimpleXML

I am working with the XML file string below and I've tried a number of methods to try and get access to certain parts of the XML contents. Please see the code after the XML file below for my attempt:
<?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>
<Address_ListResponse xmlns="http://example.example.com/">
<Address_ListResult>
<Address>
<HoldingId xsi:nil="true"/>
<MainId>1617931</MainId>
<ContactId>8</ContactId>
<Description>Home, All Purposes</Description>
<Position/>
<Department/>
<Organisation/>
<AddressLabel>Mr Joe Bloggs</AddressLabel>
<AddressLine1>1 Fake Road</AddressLine1>
<AddressLine2/>
<AddressLine3/>
<Town>Faketown</Town>
<CountyId>818</CountyId>
<PostCode>FA33 4KE</PostCode>
<CountryId>3</CountryId>
<Phone>01234567890</Phone>
<EvePhone/>
<Mobile/>
<Email>joe#bloggs.com</Email>
<Fax/>
<WWW/>
<AddressTypeId>1</AddressTypeId>
<IsBilling>true</IsBilling>
<IsMailing>true</IsMailing>
<IsDelivery>true</IsDelivery>
<IsInherited>false</IsInherited>
<GridN/>
<GridE/>
<Latitude/>
<Longitude/>
<CensationCode/>
<IsDeleted>false</IsDeleted>
<HoldingPersonalDetailsId xsi:nil="true"/>
<IsSynced>false</IsSynced>
<BeenProcessed>false</BeenProcessed>
<CountyName/>
<CountryName/>
<AddressTypeName>Home</AddressTypeName>
</Address>
</Address_ListResult>
</Address_ListResponse>
</soap:Body>
</soap:Envelope>
Code for accessing the XML content:
$xml = simplexml_load_string($result);
echo "Town: " . $xml->children('http://schemas.xmlsoap.org/soap/envelope/')->children('http://example.example.com/')->Address_ListResponse->Town;
The above code was based on a link posted by another StackOverFlow question: http://blog.preinheimer.com/index.php?/archives/172-SimpleXML,-Namespaces-Hair-loss.html
Any help would be appreciated.
Thanks.
Consider using the SOAP extension instead.
See the example in the PHP Manual on how to write a client.
An alternative would be to use Zend_Soap as a standalone component.
Turns out the answer I was looking for wasn't SimpleXML - or at least I couldn't get that to work.
What I have done is used the xml_parse_into_struct to create an array of values returned from the XML data: http://www.php.net/manual/en/function.xml-parse-into-struct.php

Categories