Getting only the child elements of the first element - php

My XML file is such as (for example):
<?xml version="1.0" encoding="UTF-8" ?>
<bikes>
<bike>
<model>First</model>
<speedNumber>4</speedNumber>
<sizes>100</sizes>
<amount>100</amount>
</bike>
<bike>
<model>Second</model>
<speedNumber>3</speedNumber>
<sizes>300</sizes>
<amount>150</amount>
</bike>
<bike>
<model>Third</model>
<speedNumber>4</speedNumber>
<sizes>300</sizes>
<amount>300</amount>
</bike>
</bikes>
How can I get child elements for the first <bike> element only?
I want to print model=First, speedNumber=4 ...
<bike>
<model>First</model>
<speedNumber>4</speedNumber>
<sizes>100</sizes>
<amount>100</amount>
</bike>
I tried this:
foreach ($xml->children(0) as $bikes)
{
foreach ($bikes->children() as $childs)
{
echo $childs->getName()."=".$childs ." ";
}
echo "<br>";
}
But it doesn't work for me.
How can I solve this problem?

You can access the elements directly using array syntax:
$bikes->bike[0]->model
$bikes->bike[0]->speedNumber
...
Full code:
<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8" ?>
<bikes>
<bike>
<model>First</model>
<speedNumber>4</speedNumber>
<sizes>100</sizes>
<amount>100</amount>
</bike>
<bike>
<model>Second</model>
<speedNumber>3</speedNumber>
<sizes>300</sizes>
<amount>150</amount>
</bike>
<bike>
<model>Third</model>
<speedNumber>4</speedNumber>
<sizes>300</sizes>
<amount>300</amount>
</bike>
</bikes>
XML;
$bikes = new SimpleXMLElement($xml);
echo $bikes->bike[0]->model . "\n";
echo $bikes->bike[0]->speedNumber . "\n";
echo $bikes->bike[0]->sizes . "\n";
echo $bikes->bike[0]->amount . "\n";
?>
Tested here: http://codepad.org/yVAyoPtG

Related

Load Foreach loop into string as XML

I'm trying to load a foreach into a string formatted as XML.
I've tried as follows
<?php
$data = '<?xml version="1.0" encoding="utf-8" ?><markers>';
foreach ($entries as $entry => $marker ) {
'<marker name="' . $marker->getName() . '"'.'lat="' . $marker->getLatitude() . '"'.'lng="' . $marker->getLongitude() . '"'.'address="' . $marker->getAddressLineOne() . '"'.'address2="' . $marker->getAddressLineTwo() . '"'.'city="' . $marker->getCitySuburb() . '"'.'state="' . $marker->getState('fieldName') . '"'.'postal="' . $marker->getPostCode() . '"'.'country="' . $marker->getCountry('fieldName') . '"'.'phone="' . $marker->getPhone() . '"'.'email="' . $marker->getEmail() . '"'.'web="' . $marker->getWebSite() . '"'.'/>';
}
'</markers>';
?>
But what I end up getting is:
nothing in the $data variable
for some reason each item is nesting in the previous item
Basically I would like to achieve the following result:
<?php
$data = '<?xml version="1.0" encoding="utf-8"?>
<markers>
<marker name="Chipotle Minneapolis" lat="44.947464" lng="-93.320826" category="Restaurant" address="3040 Excelsior Blvd" address2="" city="Minneapolis" state="MN" postal="55416" country="US" phone="612-922-6662" email="info#chipotle.com" web="http://www.chipotle.com" />
<marker name="Chipotle St. Louis Park" lat="44.930810" lng="-93.347877" category="Restaurant" address="5480 Excelsior Blvd." address2="" city="St. Louis Park" state="MN" postal="55416" country="US" phone="952-922-1970" email="info#chipotle.com" web="http://www.chipotle.com" />
<marker name="Chipotle Minneapolis" lat="44.9553438" lng="-93.29719699999998" category="Restaurant, Bar" address="2600 Hennepin Ave." address2="" city="Minneapolis" state="MN" postal="55404" country="US" phone="612-377-6035" email="info#chipotle.com" web="http://www.chipotle.com" />
</markers>';
?>
Thanks
Said
Revised code
<?php
$data = simplexml_load_string("<markers />");
foreach ($entries as $entry => $marker ) {
$newMarker = $data->addChild("marker");
$newMarker->addAttribute("name", $marker->getName());
$newMarker->addAttribute("lat", $marker->getLatitude());
$newMarker->addAttribute("lng", $marker->getLongitude());
$newMarker->addAttribute("state", $marker->getPostCode());
}
echo $data->asXML();
?>
<?php
echo var_dump($data);
?>
After the first line where you use
$data = '<?xml version="1.0" encoding="utf-8" ?><markers>';
you don't add any of the further text onto the variable. You need to use something like
$data .='<marker name="' . $marker->getName() .`
(with the dot before the = to add the value), you also need to be careful with the spacing and the quotes.
I would also recommend using something like SimpleXML to build the XML rather than using put text, it is longer code but safer. Something like...
$xml = simplexml_load_string("<markers />");
foreach ($entries as $entry => $marker ) {
$newMarker = $xml->addChild("marker");
$newMarker->addAttribute("name", $marker->getName());
$newMarker->addAttribute("lat", $marker->getLatitude());
$newMarker->addAttribute("lng", $marker->getLongitude());
// Repeat for all attributes
}
echo $xml->asXML();
Since it's not clear to me how $entries are generated, I'll make up some data in couple of arrays and create a simplified version of your expected output, with the help of a function borrowed from here. Obviously, you'll need to modify it to fit your actual code.
$data = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<markers>
</markers>
XML;
$xml = simplexml_load_string($data);
function sxml_append(SimpleXMLElement $to, SimpleXMLElement $from) {
$toDom = dom_import_simplexml($to);
$fromDom = dom_import_simplexml($from);
$toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));
}
$stores = ["Chipotle Chicago","Chipotle St. Louis Park","Chipotle Minneapolis"];
$locations = ["Chicago","St. Louis Park","Minneapolis"];
$destination = $xml->xpath('//markers');
foreach(array_combine($stores, $locations) as $store => $location) {
$tm = simplexml_load_string('<marker name="xxx" city="yyy"/>');
$tmxml = $tm->xpath('//marker')[0];
$tmxml['name'] = $store;
$tmxml['city'] = $location;
sxml_append($destination[0], $tmxml);
}
echo $xml->asXML();
Output:
<?xml version="1.0" encoding="UTF-8"?>
<markers>
<marker name="Chipotle Chicago" city="Chicago" />
<marker name="Chipotle St. Louis Park" city="St. Louis Park" />
<marker name="Chipotle Minneapolis" city="Minneapolis" />
</markers>

how to get elements values from simple xml

I have the following xml document:
<?xml version="1.0"?>
<root>
<offers count="3009">
<offer>
<offerId>25</offerId>
<offer_type>for sale</offer_type>
<offer_status>available</offer_status>
<building_floors></building_floors>
<title>title</title>
<photos count="4">
<photo zIndex="1">1.jpg</photo>
<photo zIndex="2">2.jpg</photo>
<photo zIndex="3">3.jpg</photo>
<photo zIndex="4">4.jpg</photo>
</photos>
</offer>
</offers>
</root>
I am using this php code to get results from the xml:
$xml = simplexml_load_file("offers.xml")
or die("Error: Cannot create object");
foreach($xml->children() as $offers){
foreach($offers->children() as $offer => $data){
echo $data->offerId;echo "<br />";//and so on for each element
foreach ($xml->offers->offer->photos->photo as $aaa){
$photos=$aaa; echo "<br />";
//echo $xml;
$photo = explode("<br /> ", $photos);
foreach($photo as $value) echo $value; echo '<br />';//echo $value
}
}
}
When I try to loop the photo element I get all photos but only for the first offer.
My question is what I am doing wrong and why I do not get photos for each offer?
The problem is with the way you retrieve the photo elements. You start from the root element so it always give you the same node.
You should use $data like this :
foreach ($data->photos->photo as $aaa){
cleaning a bit your code you should use this to display the photo elements:
$xml = simplexml_load_file("offers.xml") or die("Error: Cannot create object");
foreach($xml->children() as $offers){
foreach($offers->children() as $offer){
echo "Offer id : " . $offer->offerId . "<br>";
foreach ($offer->photos->photo as $photo){
$val = (string) $photo;
echo $val . "<br>";
}
}
}

retrieve atom:id from XML

How do you retrieve the value in atom:id from a XML document?
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
<atom:id>http://www.google.com/m8/feeds/profiles/domain/mydomain.com/full/test</atom:id>
</atom:entry>
You can use SimpleXML and XPath for that:
$xml = <<<XML
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
<atom:id>http://www.google.com/m8/feeds/profiles/domain/mydomain.com/full/test</atom:id>
</atom:entry>
XML;
$xml = new SimpleXMLElement($xml);
$result = $xml->xpath('/atom:entry/atom:id');
foreach ($result as $curResult)
{
echo __FILE__ . ':' . __LINE__ . '<pre>' . print_r($curResult, 1) . '</pre>';
}
You could use simple_xml and an xpath query. Like so:
$xml = <<<EOF
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
<atom:id>http://www.google.com/m8/feeds/profiles/domain/mydomain.com/full/test</atom:id>
</atom:entry>
EOF;
$doc = simplexml_load_string($xml);
$el = $doc->xpath('//atom:id');
echo (string)$el[0];
(obviously that's without error checking and all)

xml manipulation with php

I am new to PHP so maybe this is silly question.
How can I easily manipulate with xml document using PHP and get data from it?
Can someone show me some example how it is done?
I tried this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
And this is my php:
<?php
$xml = simplexml_load_file("test.xml");
echo $xml->getName() . "<br />";
foreach($xml->children() as $child)
{
echo $child->getName() . ": " . $child . "<br />";
}
?>
This works for only this document, but when i try some bigger xml it doesn't work. It only writes back one tag all the time.
Your problem is that with your code you only fetch first nodes of xml documents. Try like this:
$xml = simplexml_load_file($url) ;
echo '<br /><b>all of the data:</b>'.'<br> </br><div class="data">';
echo $xml->getName() . "<br />";
foreach($xml -> children() as $name => $child ){
echo $name.'<br />';
foreach($child -> children() as $name1 => $child1 ) {
echo $name1.'<br />'; //fetching children nodes
foreach($child1 -> children() as $name2 => $child2 ) {
echo $name2.'<br />';
}
// ..... and so on...depends how deep is you node tree
}
}
you can use xpath to fetch what you want. It's easy and you can build queries with it. Try like this:
$result=$xml->xpath($your_query);
foreach($result as $bla) {
echo "$bla<br />";
}
You can use this CD catalog to test you code: http://www.w3schools.com/xml/cd_catalog.xml
Here are some examples of using xpath: http://www.w3schools.com/xpath/xpath_examples.asp

PHP access XML node element

I am trying to edit some XML with PHP. Currently the XML looking something like:
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Main Title</title>
<link>http://exmaple.com</link>
<description> blahblahblah </description>
<language>en</language>
<item>
<title>Tite1</title>
<link>http://www.example.com (THIS IS WHAT I WANT)</link>
<description>blah blah blah</description>
</item>
.
.
.
</channel>
</rss>
I've tried to access the 2nd level link but my code only changes the first Link node value. Here is the code:
$xml->load('http://www.google.com/doodles/doodles.xml');
$element = $xml->getElementsByTagName('channel')->item(0);
$secondlvl = $element->getElementsByTagName('item')->item(0);
$2ndlevellinknode = $element->getElementsByTagName('link')->item(0);
$2ndlevellinknode->nodeValue = $newvalue;
Any suggestions? Also is it possible to use this line of code in a for loop like this
for ($i = 0; $i <= 20; $i++) {
$element = $xml->getElementsByTagName('channel')->item(0);
$secondlvl = $element->getElementsByTagName('item')->item(0);
$2ndlevellinknode = $element->getElementsByTagName('link')->item($i);
$2ndlevellinknode->nodeValue = $newvalue;
}
this should give you an idea.
$f = simplexml_load_file('test.xml');
print $f->channel->title . "\n";
print $f->channel->link . "\n";
print $f->channel->description . "\n";
foreach($f->channel->item as $item) {
print $item->title . "\n";
}

Categories