I need to display data from an external XML feed on my site but I have absolutely no idea where to start. What would be the full PHP code to grab the XML feed and print the following elements into my page:
<name></name>
<status></status>
<pin></pin>
<picture>
</picture>
<description></description>
<category name="skills">
<skill></skill>
</category>
<category name="tools">
<tool></tool>
<tool></tool>
<tool></tool>
</category>
<category name="subjects">
<subject></subject>
</category>
You can use php built in function called simplexml_load_string along with file_get_contents.
What the two functions do is convert the url xml feed to a string and then create an object stored into $xml.
Resource file_get_contents
Resource simplexml_load_string
$url = 'yourXMLfeed.xml';
$xml = file_get_contents($url);
$xml = simplexml_load_string($xml);
You can then access your data inside <name></name>, etc like so:
echo $xml->name will print the data inside of the name tags.
If you have a nested xml feed you can also use foreach like so:
foreach($xml as $x):
echo $x->name
endforeach;
EDIT
Let say each of your <tool></tool> had data ie:
<tool>Wrench</tool> <tool>Hammer</tool> <tool>Screwdriver</tool>
You could do a quick foreach loop to get the data like so:
foreach($xml->category[1] as $tool) {
echo $tool.' ';
}
This would echo out Wrench Hammer Screwdriver
Related
So i am hitting a soap service, when i get the data and parse it through simplexml_load_string in order to access the data as an object (or just basically access the data) simplexml_load_string seems to strip it out.
A Raw response from soap service looks like:
A result parsed through simplexml_load_string
using the following code:
$result = simplexml_load_string((string)$result->DisplayCategoriesResult->any);
i get a result of:
this looks correct but at a closer look you will notice its just id's and the names of the categories are left behing simplexml_load_string
how can i manage to get the proper result? if there is another way of getting the raw data into a "usable" form or object that solution is also welcome
The text content of XML nodes doesn't show up when using print_r or var_dump, etc. They aren't "traditional" PHP objects, so you can't use the standard debugging options.
To access the text content (whether embedded as CDATA or otherwise), you need to step down into the child elements, and then cast them to strings:
<?php
$xml = <<<XML
<randgo xmlns="">
<status>0</status>
<message>Success</message>
<categories>
<category id="53"><![CDATA[go eat]]></category>
<category id="54"><![CDATA[go do]]></category>
<category id="55"><![CDATA[go out]]></category>
</categories>
</randgo>
XML;
$sxml = simplexml_load_string($xml);
foreach ($sxml->categories->category as $category)
{
echo $category['id'] . ": " . (string) $category, PHP_EOL;
}
=
$ php simplexml_categories.php
53: go eat
54: go do
55: go out
See: https://eval.in/590975
(Sorry if there are any typos in the XML, I think I copied from the screenshot correctly...)
The category names are CDATA. Try something like this to read it.
$doc = new DOMDocument();
$doc->load((string)$result->DisplayCategoriesResult->any);
$categories = $doc->getElementsByTagName("categories");
foreach ($categories as $categorie) {
foreach($categorie->childNodes as $child) {
if ($child->nodeType == XML_CDATA_SECTION_NODE) {
echo $child->textContent . "<br/>";
}
}
}
Need help with updating some simplexml code I did along time ago. The XML file I'm parsing from is formatted in a new way, but I can't figure out how to navigate it.
Example of old XML format:
<?xml version="1.0" encoding="UTF-8"?>
<pf version="1.0">
<pinfo>
<pid><![CDATA[test1 pid]]></pid>
<picture><![CDATA[http://test1.image]]></picture>
</pinfo>
<pinfo>
<pid><![CDATA[test2 pid]]></pid>
<picture><![CDATA[http://test2.image]]></picture>
</pinfo>
</pf>
and then the new XML format (note "category name" added):
<?xml version="1.0" encoding="UTF-8"?>
<pf version="1.2">
<category name="Cname1">
<pinfo>
<pid><![CDATA[test1 pid]]></pid>
<picture><![CDATA[http://test1.image]]></picture>
</pinfo>
</category>
<category name="Cname2">
<pinfo>
<pid><![CDATA[test2 pid]]></pid>
<picture><![CDATA[http://test2.image]]></picture>
</pinfo>
</category>
</pf>
And below the old code for parsing that doesn't work since the addition of "category name" in the XML:
$pinfo = new SimpleXMLElement($_SERVER['DOCUMENT_ROOT'].'/xml/file.xml', null, true);
foreach($pinfo as $resource)
{
$Profile_id = $resource->pid;
$Image_url = $resource->picture;
// and then some echo´ing of the collected data inside the loop
}
What do I need to add or do completely different? I tried with xpath,children and sorting by attributes but no luck - SimpleXML has always been a mystery to me :)
You were iterating over all <pinfo> elements located in the root element previously:
foreach ($pinfo as $resource)
Now all <pinfo> elements have moved from the root element into the <category> elements. You now need to query those elements first:
foreach ($pinfo->xpath('/*/category/pinfo') as $resource)
The now wrong named variable $pinfo is standing a bit in the way so it better do some more changes:
$xml = new SimpleXMLElement($_SERVER['DOCUMENT_ROOT'].'/xml/file.xml', null, true);
$pinfos = $xml->xpath('/*/category/pinfo');
foreach ($pinfos as $pinfo) {
$Profile_id = $pinfo->pid;
$Image_url = $pinfo->picture;
// ... and then some echo´ing of the collected data inside the loop
}
The category elements exist as their own array when you load the XML file. The XML you are used to parsing is contained within. All you need to do is wrap your current code with another foreach. Other than that there isn't much to change.
foreach($pinfo as $category)
{
foreach($category as $resource)
{
$Profile_id = $resource->pid;
$Image_url = $resource->picture;
// and then some echo´ing of the collected data inside the loop
}
}
Let's say my XML is like this:
<?xml version="1.0"?>
<lists>
<list
path=".">
<entry
kind="dir">
<name>Assignment1.1</name>
<commit
revision="1668">
<author>netid</author>
<date>2011-09-07T03:03:58.367692Z</date>
</commit>
</entry>
<entry
kind="file">
<name>Assignment1.1/.classpath</name>
<size>397</size>
<commit
revision="1558">
<author>netid</author>
<date>2011-09-06T17:00:52.998920Z</date>
</commit>
.
.
.
</list>
</lists>
And I store it in a SimpleXML object using
$xml_list = simplexml_load_file(dirname(__FILE__).'/svn_list.xml');
How would I access for example, the revision variable containing 1558?
I can't seem to figure it out using a combination of echo and print_r.
SimpleXML uses a set of classes which implement iterators to work through them, so you can loop through each node using foreach, however the easiest way to navigate the XML once it's loaded is by using SimpleXMLElement::xPath(). To get revision 1558, you can make the following call:
$commit = $xml_list->xpath('//list/entry/commit[#revision="1558"]');
This will return you the nodes underneath <commit revision="1558">, and you can then access them from the $commit variable, which extends ArrayObject.
To get the actual content of the <author> element, you must do the following:
print((string)$commit[0]->author);
SimpleXMLElement instances need to be cast to a type to expose their actual values.
Also, if you want to dump the content of $commit to see its child nodes, the easiest way is to call the asXml() method as follows:
print($commit[0]->asXml());
You are facing difficulties because you have error on your XML file , The </entry> tag was not closed.
You could traverse like this.
<?php
$xml='<lists>
<list>
<entry
kind="dir">
<name>Assignment1.1</name>
<commit
revision="1668">
<author>netid</author>
<date>2011-09-07T03:03:58.367692Z</date>
</commit>
</entry>
<entry
kind="file">
<name>Assignment1.1/.classpath</name>
<size>397</size>
<commit
revision="1558">
<author>netid</author>
<date>2011-09-06T17:00:52.998920Z</date>
</commit>
</entry>
</list>
</lists>';
$xml = simplexml_load_string($xml);
foreach ($xml->list->entry[0]->commit->attributes() as $a=>$v)
{
echo $v;
}
OUTPUT :
1668
I have a document that it's structure is like below.
There are a lot of <entry>. My question is how can I output the <uri> of each entry? And another question, how can I output only the USERNAME?
This is the file I want to get the usernames http://search.twitter.com/search.atom?q=yankees
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns:google="http://base.google.com/ns/1.0" xml:lang="en-US" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/Atom" xmlns:twitter="http://api.twitter.com/" xmlns:georss="http://www.georss.org/georss">
<entry>
<author>
<name></name>
<uri>http://twitter.com/USERNAME</uri>
</author>
</entry>
<?php
$xml = new DOMDocument;
// link to ur file
$xml->load('');
foreach ($xml->getElementsByTagName('entry') as $product )
{
$append = array();
foreach($product->getElementsByTagName('uri') as $name ) {
// Stick $name onto the array
$append[] = $name;
}
}
$result = $xml->saveXML();
print_r(str_replace('http://twitter.com/','',$result));
?>
You can use Xpath queries
http://www.php.net/manual/en/simplexmlelement.xpath.php
or
http://php.net/manual/en/domxpath.query.php
You should use SimpleXML some kind of a loop which goes trough all the s.
(foreach($xml->entry as $entry) loop should work fine, I think.)
And for the second: if it is always http://twitter.com/USERNAME, simply count the prefix's length than use a substr.
Resources to use: substr, SimpleXML, SimpleXML
I am trying to parse an individual element from an XML string using PHP. The issue is that this individual element occurs before the entries start. The XML is below:
<?xml version="1.0" encoding="UTF-8"?>
<feed gd:kind="shopping#products" gd:etag=""lm_25heFT8yiumci9EH1kItJBpg/Sj5O9aXZ82PKpx3N2C3uQYMhNYE"" xmlns="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:s="http://www.google.com/shopping/api/schemas/2010">
<openSearch:totalResults>64</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>25</openSearch:itemsPerPage>
<entry >...</entry>
<entry >...</entry>
</feed>
I am trying to parse out the "64" in the opensearch:totalResults tag. How do I this and assign it to a variable in php? I tried:
$url = 'url of xml feed';
$xml = simplexml_load_file($url);
$entries =$xml->entry[0]->openSearch:totalResults;
// also tried $entries =$xml->openSearch:totalResults;
echo $entries;
but it's not working. Any advice?
You need to register namespace in order to access these nodes:
$xml = simplexml_load_file('file.xml');
$xml->registerXPathNamespace('os', 'http://a9.com/-/spec/opensearchrss/1.0/');
$nodes = $xml->xpath('os:totalResults');
$totalResults = (string)$nodes[0];
You can also use http://it1.php.net/manual/en/simplexmlelement.children.php (using the $ns parameter)
that is less resource intensive.