I'm trying to read an XML file in PHP which has multiple same-named nodes inside a parent. So far, I can read the first iteration of the XML node but then PHP moves to the next parent even though there's another child to be read. In this case, it's the <DEVICE> node and the child node of it which is <IPV4>.
Here's the XML (pass1.xml)
<LIST>
<COMPANY>Alpha
<DEVICE>Alpha1
<IPV4>1.2.3.4</IPV4>
</DEVICE>
<DEVICE>Alpha2
<IPV4>5.6.7.8</IPV4>
</DEVICE>
</COMPANY>
<COMPANY>Bravo
<DEVICE>Bravo1
<IPV4>1.3.5.7</IPV4>
</DEVICE>
</COMPANY>
</LIST>
As you can see, there are two devices listed under the "Alpha" company and one under the "Bravo" company. Here's my PHP (I've omitted the HTML tags):
$xml = simplexml_load_file("/var/www/xml/pass1.xml") or die ("Could not open file!");
// Get Companies
echo "Company List<br>";
foreach($xml->children() as $company) {
echo $company . "<br>";
}
echo "<br>Device List<br>";
// Get devices
foreach($xml->children() as $device) {
echo $device->DEVICE . "<br>";
}
echo "<br>IP List<br>";
// Get IP
foreach($xml->children() as $ipv4) {
echo $ipv4->DEVICE->IPV4 . "<br>";
}
The "Companies" are pulled properly but for the "Devices" I only get Alpha1 and Bravo1. Similarly, for the IP addresses I only get 1.2.3.4 and 1.3.5.7 which correspond with the devices which get pulled. I'm missing any information on Alpha2.
My ultimate goal is to have each Device and IPv4 iterated over from PHP and displayed. Can someone point me in the right direction?
I'm sure there's a better way to do this, but this code explains why yours wasn't working correctly.
// Get Companies
echo "Company List<br>";
foreach($xml->children() as $company) {
echo $company . "<br>";
}
echo "<br>Device List<br>";
// Get devices
foreach($xml->children() as $company) {
foreach ($company->children() as $device) {
echo $device . "<br>";
}
}
echo "<br>IP List<br>";
// Get IP
foreach($xml->children() as $company) {
foreach ($company->children() as $device) {
foreach ($device->children() as $IPV4) {
echo $IPV4 . "<br>";
}
}
}
The problem with your code is that in each loop you're trying to pull different information, but your code is actually only pulling the first child repeatedly.
So here
// Get devices
foreach($xml->children() as $device) {
echo $device->DEVICE . "<br>";
}
You're attempting to get each DEVICE from the XML file, but in actuality you're pulling all of the FIRST children from $xml which are COMPANY tags, and the two FIRST COMPANY tags are Alpha and Bravo. and then with EACH of those two company tags you're echoing a SINGLE DEVICE tag.
So you're pulling a SINGLE DEVICE tag from Alpha and a SINGLE DEVICE tag from Bravo. So the solution was to add another layer to your foreach, where after it loops through the two COMPANY tags, it then loops through the next layer of children of the COMPANY tags, which are the DEVICE tags.
Then for the IPV4 you do the same, but add another loop layer.
Related
I'm new to PHP and in particularly XML.
I'm trying to pull data from an XML file using the particular values of one of the child nodes. All the online resources I seem to find lead me to how to get all the values from a child node but I want to pull only the ones that contain a certain value in a child node. I'm struggling to get the format of the if statement right.
Any help, much appreciated, thank you!
My code so far:
if( !($xml = simplexml_load_file('images/database.xml')) )
{
echo "Unable to load XML file";
}
else
{
foreach($xml->children() as $document)
{
if ($xml->$document->city == $xml->$document->city['London'])
{
echo $document->name . ", ";
echo $document->description . ", ";
echo $document->image . ", <br>";
}
}
}
When trying to parse an XML document in PHP, nothing is returned.
The XML document im trying to use:
http://cdn.content.easports.com/media2011/fifa11zoneplayer/25068538/632A0001_10_ZONE_PLAYER_iUa.xml
The code I have tried:
$player = simplexml_load_file('http://cdn.content.easports.com/media2011/fifa11zoneplayer/25068538/632A0001_10_ZONE_PLAYER_iUa.xml');
foreach ($player->PlayerName as $playerInfo) {
echo $playerInfo['firstName'];
}
I have also tried:
$player = simplexml_load_file('http://cdn.content.easports.com/media2011/fifa11zoneplayer/25068538/632A0001_10_ZONE_PLAYER_iUa.xml');
echo "Name: " . $player->PlayerName[0]['firstName'];
What do I need to change for the attributes to show?
You might try to print_r the whole data youself and finally find what you need:
var_dump($player->Player->PlayerName->Attrib['value']->__toString())
//⇒ string(7) "Daniele"
To list all "values" (firstname, lastname,...) you need list all children and their attributes:
$xml = simplexml_load_file('http://cdn.content.easports.com/media2011/fifa11zoneplayer/25068538/632A0001_10_ZONE_PLAYER_iUa.xml');
foreach ($xml as $player) {
foreach ($player->PlayerName->children() as $attrib) {
echo $attrib['name'] . ': ' . $attrib['value'] . PHP_EOL;
}
}
Output:
firstName: Daniele
lastName: Viola
commonName: Viola D.
commentaryName:
This does not work, since you are trying to access an attribute and not a node value.
You might also run into problems, because the xml is not "valid" for simple xml. See my blogpost about the issues with parsing xml with php here http://dracoblue.net/dev/gotchas-when-parsing-xml-html-with-php/
If you use my Craur ( https://github.com/DracoBlue/Craur ) library instead, it will look like this:
$xml_string = file_get_contents('http://cdn.content.easports.com/media2011/fifa11zoneplayer/25068538/632A0001_10_ZONE_PLAYER_iUa.xml');
$craur = Craur::createFromXml($xml_string);
echo $craur->get('Player.PlayerName.Attrib#value'); // works since the first attrib entry is the name
If you want to be sure about the attribute (or select another one) use:
$xml_string = file_get_contents('http://cdn.content.easports.com/media2011/fifa11zoneplayer/25068538/632A0001_10_ZONE_PLAYER_iUa.xml');
$craur = Craur::createFromXml($xml_string);
foreach ($craur->get('Player.PlayerName.Attrib[]') as $attribute)
{
if ($attribute->get('#name') == 'firstName')
{
echo $attribute->get('#value');
}
}
Novice PHP programmer here (if I can even call myself that). I am currently working on a way to loop through an XML document to grab every instance of a child object that does not contain a specific keyword and then display the results. I am able to do the aforementioned but only with the first child object that is found.
Examples Follow ...
Example XML There may be more than one instance of the following and I am trying to get the <title> child element from every instance that does not contain the word "Flood" or the phrase "There are no active watches, warnings or advisories".
<entry>
<id>http://alerts.weather.gov/cap/wwaatmget.php?x=OHC095&y=0</id>
<updated>2013-04-16T20:00:01+00:00</updated>
<author>
<name>w-nws.webmaster#noaa.gov</name>
</author>
<title>There are no active watches, warnings or advisories</title>
<link href='http://alerts.weather.gov/cap/wwaatmget.php?x=OHC095&y=0'/>
</entry>
Variables
//Lucas Co. Weather
$xml_string = file_get_contents("../../cache/weather_alerts-lucas.xml");
$weather_alerts_lucas = simplexml_load_string($xml_string);
$lucas_alert = ($weather_alerts_lucas->entry->title);
$no_alert =('There are no active watches, warnings or advisories');
Displaying The Results The first if statement determines whether there should be a scroll bar or not and the second if statement determines if a specific county should display information (there are multiple counties but I am only showing one here for simplicity).
if ("$lucas_alert"=="$no_alert" || fnmatch("*Flood*", $lucas_alert))
{
//Do Nothing.
} else {
echo "<div id='emergency_bar'>";
echo "<span class='scroll_font' ... ...'>";
if ("$lucas_alert"=="$no_alert" || fnmatch("*Flood*", $lucas_alert))
{
//Do Nothing.
} else {
echo "Lucas Co. - " . $lucas_alert . " // ";
}
echo "</span>";
echo "</div>";
}
If I do it the way it is posted above it will only grab the first result and even if it grabbed multiple instances of <title> it would not display anything if one of the instances had the word "Flood" in it.
Thanks in advance. I'm not looking for someone to write code for me, just some direction.
$xml = simplexml_load_string($x); // XML in $x
$no = "There are no active watches, warnings or advisories";
foreach ($xml->xpath("//title") as $title) {
if ($title <> $no && strpos($title,"Flood") === false) echo "$title<br />";
}
see it working: http://codepad.viper-7.com/JVOoke
I am trying to parse an XML file so that I get all of the records from the <pid> tags that start with a 'b' as shown:
The link to the xml file is:
http://www.bbc.co.uk/radio1/programmes/schedules/england.xml
And the code I have so far is:
<?php
$xml = simplexml_load_file('http://www.bbc.co.uk/radio1/programmes/schedules/england.xml');
foreach($xml->day>broadcasts->broadcast as $pid){
echo $pid->programme->pid;
}
?>
As far as my knowledge goes, this foreach statement should echo out all of the pid records, where it only does the first one.
Any ideas on where my code is going wrong as to how I make it output all of them?
Your loop needs to go one level deeper, since the programme nodes are multiple children of a single broadcast node. You therefore need to loop over all the programme nodes in each broadcast node to echo out their pid
foreach($xml->day>broadcasts->broadcast as $broadcast){
// Loop over all <programme> contained in each <broadcast>
foreach ($broadcast->programme as $prog) {
echo $prog->pid;
}
}
you are iterating over whole xml structure, which contains only one "day" node.
you should position your "cursor" first on the parent of the elements you wish to iterate on :
<?php
$xml = simplexml_load_file('http://www.bbc.co.uk/radio1/programmes/schedules/england.xml');
$broadcasts = $xml->day->broadcasts;
foreach($broadcasts->broadcast as $bc) {
echo $bc->programme->pid;
}
This is a very basic question, so excuse my lack of knowledge.
I'm trying to output a JSON query from Freebase in PHP. I've already been able to parse the JSON into PHP using cURL and json_decode.
Here is a link to the JSON array (for some reason I can't get this to link directly):
http://www.freebase.com/api/service/mqlread?query={%20%22query%22%3A%20[{%20%22type%22%3A%20%22%2Fpeople%2Fperson%22%2C%20%22ns0%3Atype%22%3A%20%22%2Fbase%2Fbillionaires%2Fbillionaire%22%2C%20%22employment_history%22%3A%20[{%20%22company%22%3A%20null%20}]%2C%20%22name%22%3A%20null%20}]%20}
I'm able to ouput the first level of the array (Bill Gates), but not the 2nd level (Microsoft).
I've figured out how to display and loop through the people's names, just not their associated companies.
So my code, thus far, gets me a list of names.
$results = json_decode($response)->result;
foreach ($results as $name) {
echo $name->name . '<br/>';
I want the companies associated with each name to be displayed.
The browser-format should be:
Person 1 Name:
Company Name 1
Company Name 2
etc.
Person 2 Name:
Company Name 1
etc.
Thanks for any pointers--I'm sure that I'm just missing the simple way to structure the PHP code to display this easily.
How about:
$results = json_decode($response)->result;
foreach ($results as $person) {
echo $person->name . '<br/>';
foreach($person->employment_history as $employer) {
echo $employer->company . '<br/>';
}
echo '<hr />'; // horizontal rule for good measure
}