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;
Related
I looking into this problem for a few days now and need some help with it.
I want to access the namespaced attributes for the 'inhoud' element.
In this case, for example, I want the attribute value from the contentType attribute. So I want to grab the 'text/plain' value.
<inhoud p10:contentType="text/plain" p6:bestandsnaam="hallo 2.txt" xmlns:p10="http://www.w3.org/2005/05/xmlmime">aGFsbG8gZGFhciB4DQoNCg0K</inhoud>
It's prefixed with the p10 namespace.
Below the XML:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<updateZaakdocument_Di02 xmlns="http://www.egem.nl/StUF/sector/zkn/0310">
<edcLk02 p6:entiteittype="EDC" p6:functie="update" xmlns:p6="http://www.egem.nl/StUF/StUF0301">
<parameters>
<p6:mutatiesoort>W</p6:mutatiesoort>
</parameters>
<object p6:entiteittype="EDC" p6:sleutelVerzendend="934087" p6:verwerkingssoort="W">
<inhoud p10:contentType="text/plain" p6:bestandsnaam="hallo 2.txt" xmlns:p10="http://www.w3.org/2005/05/xmlmime">aGFsbG8gZGFhciB4DQoNCg0K</inhoud>
</object>
</edcLk02>
</updateZaakdocument_Di02>
</s:Body>
</s:Envelope>
I have tried this:
<?php
$sxe = new SimpleXMLElement($xml);
$namespaces = $sxe->getNamespaces(true);
$body = $sxe->xpath('//s:Body')[0];
$inhoud = $body->updateZaakdocument_Di02->edcLk02->object->inhoud->children($namespaces["p10"]);
print_r($inhoud);
the result is:
SimpleXMLElement Object
(
[#attributes] => Array
(
[contentType] => text/plain
)
)
I tried from there:
echo (string) $inhoud >attributes($namespaces["p10"], true)->contentType;
But never get the value out of it.
Warning: Node no longer exists in the line above
Can someone point me to the right solution here?
Thanks in advance (-:
I think when your fetching the $inhoud value, your fetching the children in the p10 namespace. What instead you need to do is fetch the attributes in the p10 namespace...
$inhoud = $body->updateZaakdocument_Di02->edcLk02->object->inhoud;
print_r($inhoud);
echo "contentType=".(string)$inhoud->attributes($namespaces["p10"])->contentType;
This outputs...
SimpleXMLElement Object
(
[0] => aGFsbG8gZGFhciB4DQoNCg0K
)
contentType=text/plain
Also when using the various methods using namespaces, the second parameter is to flag that your using the prefix. When using $namespaces["p10"] this is the URI and so you should leave the second parameter out.
I have a valid XML file (generated from SharePoint) which looks like this (in browser):
Sample XML File
<?xml version="1.0" encoding="utf-8"?>
<feed xml:base="https://www.example.com/_api/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml">
<id>9913f043-xxxx-xxxx-xxxx-xxxx-xxxx</id>
<title />
<updated>2017-05-23T06:08:01Z</updated>
<entry m:etag=""23"">
<id>Web/Lists(guid'13306095-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx')/Items(1)</id>
<category term="SP.Data.XXXXXXXXXXXXXXXXXXXXX" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link rel="edit" href="Web/Lists(guid'13306095-xxxx-xxxx-xxxx-xxxx-xxxx')/Items(1)" />
<title />
<updated>2017-05-23T06:08:01Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:FileSystemObjectType m:type="Edm.Int32">0</d:FileSystemObjectType>
<d:Id m:type="Edm.Int32">1</d:Id>
<d:ContentTypeId>0x0100B6A3B67BE96F724682CCDC8FBE9D70C2</d:ContentTypeId>
<d:Title m:null="true" />
<d:Topic>How to google?</d:Topic>
<d:Cats m:type="Collection(Edm.Int32)">
<d:element>1</d:element>
<d:element>2</d:element>
<d:element>3</d:element>
<d:element>4</d:element>
<d:element>5</d:element>
<d:element>6</d:element>
<d:element>7</d:element>
</d:Cats>
</m:properties>
</content>
</entry>
<entry>
.
.
</entry>
<entry>
.
.
</entry>
</feed>
(Note: I cut off some repeated nodes here, because it is so long.)
Clearly, we have inner nodes <content type="application/xml"> which also contain data inside.
The Problem (When parsing with PHP)
In PHP, i used this codes to parse (trying to extract it):
$xml = simplexml_load_file("data.xml");
foreach ($xml->entry as $item) {
echo $item->updated . PHP_EOL; // <--- This works!
print_r($item->content); // <--- This doesn't work as expected.
}
.. and then, it is giving me these:
2017-05-23T06:08:01Z
SimpleXMLElement Object
(
[#attributes] => Array
(
[type] => application/xml
)
)
2017-05-23T06:08:01Z
SimpleXMLElement Object
(
[#attributes] => Array
(
[type] => application/xml
)
)
.
.
Question (Help!)
How do i extract (get) the actual data inside those <content type="application/xml"> nodes, please?
Please help. Thank you in advance.
The elements below "content" have a namespace (d:...). I had the same problem a while ago. This should help:
$xml = simplexml_load_file("data.xml");
foreach ($xml->entry as $item) {
echo $item->updated . PHP_EOL;
$ns = $item->content->children('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata');
print_r($ns->properties);
}
I updated the code. I'm shure print_r($ns->properties) doesn't show the complete sub-elements ... because they are from another namspace. I guess you can then do this:
$nsd = $ns->properties->children("http://schemas.microsoft.com/ado/2007/08/dataservices");
and proccced with the result.
In your example namespaces can be found in the document element:
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
(use the URL between the quotation marks)
d: and m: are used in the document to reference these namespaces.
EDIT: There is another namespace involved. Didn't recognize that. The solution can be atapted. I changed the code a bit.
I had a very similar issue. I was finally able to get my example working with this.
function pre($array){
echo "<pre>";
print_r($array);
echo "</pre>";
}
$record[$count]['id'] = $id->id;
$xmlData = utf8_encode(file_get_contents("https://ucf.uscourts.gov/odata.svc/Creditors(guid'81044f71-fb3c-11e5-ac5b-0050569d488e')"));
$xml = new SimpleXMLElement($xmlData);
$properties = $xml->content->children('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata');
$fields = $properties->properties->children("http://schemas.microsoft.com/ado/2007/08/dataservices");
pre($fields);
$key = (string)$fields->Key;
$lastName = (string)$fields->LastName;
echo $key. "<br />";
echo $lastName. "<br />";
You would need to replace the Url in file_get_contents, the Key variable and LastName variable with you namespace values that you are looking for and I like to use a pre function to have things show easier. You can remove this part. Hopes this helps someone.
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]);
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);
I have an xml file
<?xml version="1.0" encoding="utf-8"?>
<xml>
<events date="01-10-2009" color="0x99CC00" selected="true">
<event>
<title>You can use HTML and CSS</title>
<description><![CDATA[This is the description ]]></description>
</event>
</events>
</xml>
I used xpath and and xquery for parsing the xml.
$xml_str = file_get_contents('xmlfile');
$xml = simplexml_load_string($xml_str);
if(!empty($xml))
{
$nodes = $xml->xpath('//xml/events');
}
i am getting the title properly, but iam not getting description.How i can get data inside
the cdata
SimpleXML has a bit of a problem with CDATA, so use:
$xml = simplexml_load_file('xmlfile', 'SimpleXMLElement', LIBXML_NOCDATA);
if(!empty($xml))
{
$nodes = $xml->xpath('//xml/events');
}
print_r( $nodes );
This will give you:
Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[date] => 01-10-2009
[color] => 0x99CC00
[selected] => true
)
[event] => SimpleXMLElement Object
(
[title] => You can use HTML and CSS
[description] => This is the description
)
)
)
You are probably being misled into thinking that the CDATA is missing by using print_r or one of the other "normal" PHP debugging functions. These cannot see the full content of a SimpleXML object, as it is not a "real" PHP object.
If you run echo $nodes[0]->Description, you'll find your CDATA comes out fine. What's happening is that PHP knows that echo expects a string, so asks SimpleXML for one; SimpleXML responds with all the string content, including CDATA.
To get at the full string content reliably, simply tell PHP that what you want is a string using the (string) cast operator, e.g. $description = (string)$nodes[0]->Description.
To debug SimpleXML objects and not be fooled by quirks like this, use a dedicated debugging function such as one of these: https://github.com/IMSoP/simplexml_debug
This could also be another viable option, which would remove that code and make life a little easier.
$xml = str_replace("<![CDATA[", "", $xml);
$xml = str_replace("]]>", "", $xml);