dynamcially retrieve xml data - php

I am working with simplexml to retrieve data.
The data I am having trouble with looks like this:
SimpleXMLElement Object
(
[listing_pics_array] => SimpleXMLElement Object
(
[pic0] => http://imagepath.com_1.jpg
[pic1] => http://imagepath.com_2.jpg
[pic2] => http://imagepath.com_3.jpg
[pic3] => http://imagepath.com_4.jpg
[pic4] => http://imagepath.com_5.jpg
[pic5] => http://imagepath.com_6.jpg
[pic6] => http://imagepath.com_7.jpg
)
)
I am able to retrieve the url like this:
(string)$listing->listing_pics_array->pic0[0]
I want to dynamically loop over the listing_pic_array because I have no idea how many pics will be returned.
I want to do something like this:
foreach ($listing->listing_pics_array as $key => $value) {
echo '<img src="'.$value .'" alt="" />';
}
but I am getting nothing returned.
Thanks.

Try casting the SimpleXMLElement into an Array. This one works fine for me:
$sXml = <<<XML
<?xml version='1.0'?>
<root>
<listing_pics_array>
<pic0>pic0 foo</pic0>
<pic1>pic1 bar</pic1>
</listing_pics_array>
</root>
XML;
$oXml = simplexml_load_string($sXml);
foreach ((array)$oXml->listing_pics_array as $sCurrentValue) {
echo $sCurrentValue . PHP_EOL;
}
Yielded
pic0 foo
pic1 bar
HTH

Related

each node attribute value of xml in php

Im trying to get the catId value. But i can see only the category value.
My xml file looks below:
<sample>
<Item ItemNumber="00000088" FormattedItemNumber="00000-088">
<CompatibleModels />
<Category CatId="160" > test 123 </Category>
<Images />
<Documents />
<RequiredItems />
</Item>
</sample>
$xml = simplexml_load_file("test.xml");
print_r($xml);
[sample] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[ItemNumber] => 00000088
[FormattedItemNumber] => 00000-088
)
[Category] => Bags/Luggage 123
)
how can get the CatId value? Why the cateId value is missing?
You can do it by many ways. Let's try-
foreach ($xml as $items) {
echo $items->Category['CatId'];
}
WORKING DEMO: https://3v4l.org/Onqe2
print_r doesn't really work with SimpleXML objects. But from the sample data you have provided you can simply access the CatId attribute using
echo $xml->Item->Category['CatId'];
You can loop and get it by using following snippet, please refer inline documentation for explanation
$xml1 = simplexml_load_file("test.xml") or die("Error: Cannot create object");
foreach ($xml1->children() as $items1) { // children mean item
echo ($items1->category['catid']); // for category tag get catid attribute
}

Parsing very simple XML with PHP

Very simple request (I think) that I have had no luck with.
Here is the contents of the xml file:
<?xml version="1.0" encoding="utf-8"?>
<status USER_ID="xxxxx">OK</status>
Current php:
$xml=simplexml_load_file($file) or die("Error: Cannot create object");
print_r($xml);
Outputs:
SimpleXMLElement Object ( [#attributes] => Array ( [USER_ID] => xxxxx ) [0] => OK )
And now I'm stuck
How can I get the value of USER_ID and that the status was "OK" into my php script.
Thanks.
Try this one below
echo "Display the user id: " . $xml['USER_ID'];
echo "Display the status: " . $xml[0];
Hope this will help you.
If you don't like SimpleXml (like me), you can also use the XMLReader Class like:
$XMLReader = new XMLReader;
$XMLReader->XML(file_get_contents($file)); //you can use $XMLReader->open('file://'.$file); too
//move to first node
$XMLReader->read();
//get an attribute
echo "USER_ID:".$XMLReader->getAttribute('USER_ID')."\n";
//get the contents of the tag as a string
echo "Status:" .$XMLReader->readString();
Output:
USER_ID:xxxxx
Status:OK
Sandbox

Problems with a foreach loop in a SimpleXMLelement

I'm trying to teach myself to handle the SimpleXMP_read_file command / object.
So I have looked deeply into the problem at "simpleXMLElement attributes and foreach" (
simpleXMLElement attributes and foreach ).
copied it bit by bit into my PHP browser and ran it.
test.xml:
<?xml version="1.0" encoding="utf-8"?>
<response result="0">
<reports>
<get count="2">
<row a="first" b="second" comment="test" c=""/>
<row a="first1" b="second2" comment="test2" c=""/>
</get>
</reports>
</response>
modified the php like this:
PHP:
$xml = simplexml_load_file('test.xml');
$rows = $xml->xpath('reports/get/row');
foreach($rows as $row)
{
foreach($row->attributes() as $key)
{
echo ('test: '.$key['a'] .' '.$key['b'].' '.$key['comment'].' '.$key['c'].'<br>') ;
}
}
I get no errors but only 2 lines :
test
test
No data.
Can anyone tell me why ?
You are doing a foreach over $row->attributes(). Therefore each iteration of the loop is a different attribute. None of the attributes have a $key['a'] value set.
You probably want to do:
foreach($rows as $row){
$key = $row->attributes();
echo 'test: '.$key['a'] .' '.$key['b'].' '.$key['comment'].' '.$key['c'].'<br>';
}
after doing a print_r($rows); i have got the following. Now you can access the array elements and class objects directly by $row->attributes['a'] etc.
foreach($rows as $row){
$xmlObjElement = json_decode(json_encode((array)$row), TRUE);
foreach($xmlObjElement as $fo){
print_r( $fo );
}
}
Output:
Array
(
[a] => first1
[b] => second2
[comment] => test2
[c] =>
)
Now you can access like $fo['a'] etc...

Getting an entire value from XML

How do I get the entire result from XML using simplexml_load_string?
My XML looks like this
<xml>
<code>
<codedesc>Code Name</codedesc>
100
</code>
<code>
<codedesc>Code Name 2</codedesc>
200
</code>
</xml>
When I load it with PHP using this code
$XML = simplexml_load_string($data);
print_r($XML);
I only get codedesc and not the code number as you can see here
https://eval.in/51562
You need to wrap your values in XML so that they can be accessed.
<xml>
<code>
<codedesc>Code Name</codedesc>
<value>100</value>
</code>
<code>
<codedesc>Code Name 2</codedesc>
<value>200</value>
</code>
</xml>
You can then access them like so:
$xml = simplexml_load_string($data);
echo $xml->code[0]->value; //100
echo $xml->code[1]->value; //200
echo $xml->code[1]->codedesc; //Code Name 2
If you can't change your xml, the following should work:
echo $xml->code[0]; //100
echo $xml->code[1]; //200
I'm not sure what you're trying to get SimpleXML correctly parses your XML string, and returns a class with an array called 'code', that has 2 objects called codedesc:
SimpleXMLElement Object
(
[code] => Array
(
[0] => SimpleXMLElement Object
(
[codedesc] => Code Name
)
[1] => SimpleXMLElement Object
(
[codedesc] => Code Name 2
)
)
)
If you're trying to get to the values (100, 200) - try putting them in XML elements.
If you're trying to print the entire XML, try print_r($XML->asXML()) (see this)

access php simplexml with namespaces

-
Hello Everyone,
I'm trying to access data in a XML file:
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://dublincore.org/documents/dcmi- namespace/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd";>
<responseDate>2013-04-15T12:14:31Z</responseDate>
<ListRecords>
<record>
<header>
<identifier>
a1b31ab2-9efe-11df-9922-efbb156aa6c1:01442b82-59a4-627e-800f-c63de74fc109
</identifier>
<datestamp>2012-08-16T14:42:52Z</datestamp>
</header>
<metadata>
<oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd";>
<dc:description>...</dc:description>
<dc:date>1921</dc:date>
<dc:identifier>K11510</dc:identifier>
<dc:source>Waterschap Vallei & Eem</dc:source>
<dc:source>...</dc:source>
<dc:source>610</dc:source>
<dc:coverage>Bunschoten</dc:coverage>
<dc:coverage>Veendijk</dc:coverage>
<dc:coverage>Spakenburg</dc:coverage>
</oai_dc:dc>
</metadata>
<about>...</about>
</record>
This a a example of the XML.
I need to access data like dc:date dc:source etc.
Anyone any ideas?
Best regards,
Tim
-- UPDATE --
I'm now trying this:
foreach( $xml->ListRecords as $records )
{
foreach( $records AS $record )
{
$data = $record->children( 'http://www.openarchives.org/OAI/2.0/oai_dc/' );
$rows = $data->children( 'http://purl.org/dc/elements/1.1/' );
echo $rows->date;
break;
}
break;
}
You have nested elements that are in different XML namespaces. In concrete you have got two additional namespaces involved:
$nsUriOaiDc = 'http://www.openarchives.org/OAI/2.0/oai_dc/';
$nsUriDc = 'http://purl.org/dc/elements/1.1/';
The first one is for the <oai_dc:dc> element which contains the second ones * <dc:*>* elements like <dc:description> and so on. Those are the elements you're looking for.
In your code you already have a good nose how this works:
$data = $record->children( 'http://www.openarchives.org/OAI/2.0/oai_dc/' );
$rows = $data->children( 'http://purl.org/dc/elements/1.1/' );
However there is a little mistake: the $data children are not children of $record but of $record->metadata.
You also do not need to nest two foreach into each other. The code example:
$nsUriOaiDc = 'http://www.openarchives.org/OAI/2.0/oai_dc/';
$nsUriDc = 'http://purl.org/dc/elements/1.1/';
$records = $xml->ListRecords->record;
foreach ($records as $record)
{
$data = $record->metadata->children($nsUriOaiDc);
$rows = $data->children($nsUriDc);
echo $rows->date;
break;
}
/** output: 1921 **/
If you are running into problems like these, you can make use of $record->asXML('php://output'); to show which element(s) you are currently traversing to.
I think this is what you're looking for. Hope it helps ;)
use DomDocument for this like access to dc:date
$STR='
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://dublincore.org/documents/dcmi- namespace/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd";>
<responseDate>2013-04-15T12:14:31Z</responseDate>
<ListRecords>
<record>
<header> <identifier> a1b31ab2-9efe-11df-9922-efbb156aa6c1:01442b82-59a4-627e-800f-c63de74fc109 </identifier>
<datestamp>2012-08-16T14:42:52Z</datestamp>
</header>
<metadata>
<oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd";>
<dc:description>...</dc:description>
<dc:date>1921</dc:date>
<dc:identifier>K11510</dc:identifier>
<dc:source>Waterschap Vallei & Eem</dc:source>
<dc:source>...</dc:source>
<dc:source>610</dc:source>
<dc:coverage>Bunschoten</dc:coverage>
<dc:coverage>Veendijk</dc:coverage>
<dc:coverage>Spakenburg</dc:coverage>
</oai_dc:dc>
</metadata>
<about>...</about>
</record>';
$dom= new DOMDocument;
$STR= str_replace("&", "&", $STR); // disguise &s going IN to loadXML()
// $dom->substituteEntities = true; // collapse &s going OUT to transformToXML()
$dom->recover = TRUE;
#$dom->loadHTML('<?xml encoding="UTF-8">' .$STR);
// dirty fix
foreach ($dom->childNodes as $item)
if ($item->nodeType == XML_PI_NODE)
$dom->removeChild($item); // remove hack
$dom->encoding = 'UTF-8'; // insert proper
print_r($doc->getElementsByTagName('dc')->item(0)->getElementsByTagName('date')->item(0)->textContent);
output:
1921
or access to dc:source
$source= $doc->getElementsByTagName('dc')->item(0)->getElementsByTagName('source');
foreach($source as $value){
echo $value->textContent."\n";
}
output:
Waterschap Vallei & Eem
...
610
or give you array
$array=array();
$source= $doc->getElementsByTagName('dc')->item(0)->getElementsByTagName("*");
foreach($source as $value){
$array[$value->localName][]=$value->textContent."\n";
}
print_r($array);
output:
Array
(
[description] => Array
(
[0] => ...
)
[date] => Array
(
[0] => 1921
)
[identifier] => Array
(
[0] => K11510
)
[source] => Array
(
[0] => Waterschap Vallei & Eem
[1] => ...
[2] => 610
)
[coverage] => Array
(
[0] => Bunschoten
[1] => Veendijk
[2] => Spakenburg
)
)
Using XPath makes dealing with namespaces more straightforward:
<?php
// load the XML into a DOM document
$doc = new DOMDocument;
$doc->load('oai-response.xml'); // or use $doc->loadXML($xml) for an XML string
// bind the DOM document to an XPath object
$xpath = new DOMXPath($doc);
// map all the XML namespaces to prefixes, for use in XPath queries
$xpath->registerNamespace('oai', 'http://www.openarchives.org/OAI/2.0/');
$xpath->registerNamespace('oai_dc', 'http://www.openarchives.org/OAI/2.0/oai_dc/');
$xpath->registerNamespace('dc', 'http://purl.org/dc/elements/1.1/');
// identify each record using an XPath query
// collect data as either strings or arrays of strings
foreach ($xpath->query('oai:ListRecords/oai:record/oai:metadata/oai_dc:dc') as $item) {
$data = array(
'date' => $xpath->evaluate('string(dc:date)', $item), // $item is the context for this query
'source' => array(),
);
foreach ($xpath->query('dc:source', $item) as $source) {
$data['source'][] = $source->textContent;
}
print_r($data);
}

Categories