I am having a hard time trying to understand why I can't compare the values of two arrays in PHP. If I echo both of these during the loop using "echo $description->ItemDesriptionName;" and "echo $item->ItemName;" the values seem to show as the same, but when I try to compare them using if, nothing works. What am I missing?
<?php
$xml=simplexml_load_file("test.xml") or die("Error: Cannot create object");
$categories = $xml->Menu->Categories;
$items = $xml->Menu->Categories->Items->ItemObject;
$itemdescription = $xml->Menu->Options->Description->DescriptionObject;
foreach($items as $item) {
echo $item->ItemName . ' - ' . $item->Price . '</br>';
foreach ($itemdescription as $description) {
if ($description->ItemDescriptionName == $item->ItemName) {
echo 'We have a match!';
//where I would echo $description->ItemDescription;
}
}
}
?>
Here is the XML file
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Menu>
<Categories>
<Name>Category 1</Name>
<Items>
<ItemObject>
<ItemName>Item 1</ItemName>
<Price>1</Price>
</ItemObject>
<ItemObject>
<ItemName>Item 2</ItemName>
<Price>3</Price>
</ItemObject>
</Items>
</Categories>
<Options>
<Description>
<DescriptionObject>
<ItemDescriptionName>Item 1</ItemDescriptionName>
<ItemDescription>A Great item</ItemDescription>
</DescriptionObject>
<DescriptionObject>
<ItemDescriptionName>Item 2</ItemDescriptionName>
<ItemDescription>A Great item as well</ItemDescription>
</DescriptionObject>
</Description>
</Options>
</Menu>
</Root>
compare as string
and you have typo in ItemDescriptioName (ItemDescriptionName)
if ( (string)$description->ItemDescriptionName == (string)$item->ItemName) {
Convert to string and then compare
<?php
$xml=simplexml_load_file("test.xml") or die("Error: Cannot create object");
$menu = $xml->Menu;
$categories = $xml->Menu->Categories;
$items = $xml->Menu->Categories->Items->ItemObject;
$itemdescription = $xml->Menu->Options->Description->DescriptionObject;
foreach($items as $item) {
$itemname = $item->ItemName;
foreach ($itemdescription as $description) {
$descriptionname = $description->ItemDescriptionName ;
echo $itemname." ---- ".$descriptionname."<br/>";
if((string)$itemname === (string)$descriptionname){
echo "Yes its matched";
}
}
}
?>
Working fine for me
The properties like $description->ItemDescriptionName are SimpleXMLElement objects. So you do not compare strings but two objects.
SimpleXMLElement objects implement the magic method __toString(). They can be cast to string automatically, but a compare between to objects will not trigger that. You can force it:
if ((string)$description->ItemDescriptionName === (string)$item->ItemName) {
...
Can you access them directly instead using an accordant index?
...
$items = $xml->Menu->Categories->Items->ItemObject;
$itemdescription = $xml->Menu->Options->Description;
$i = 0;
foreach ($items as $item) {
echo $i.' '.$item->ItemName . ' - ' . $item->Price;
echo $itemdescription->DescriptionObject[$i]->ItemDescriptionName[0];
echo ' ';
echo $itemdescription->DescriptionObject[$i]->ItemDescription[0];
echo '</br>';
$i++;
}
Related
Trying to parse the following xml:
<?xml version="1.0"?>
<devices>
<device name="TEMP" index="0" available="1" type="" id="xxx">
<field type="2" max="50" min="-20" niceName="Temperature (C)" value="24.75" key="TempC"/>
<field type="2" max="122" min="-4" niceName="Temperature (F)" value="76.55" key="TempF"/>
and pull the TempF value of 76.55.
This is the code I was trying, but I'm not doing something isn't right:
$xml = simplexml_load_file('c:\data.xml') or die("Error: Cannot create object");
echo '<h2>Server Temperature</h2>';
$list = $xml->devices;
for ($i = 0; $i < count($list); $i++) {
echo 'Temp: ' .$list[$i]->TempF[value] . '<br>';
You can loop $devices->device instead without instead of using a for loop
echo '<h2>Server Temperature</h2>';
foreach ($xml->device as $device) {
foreach ($device->field as $field) {
$att = $field->attributes();
if ((string)$att->key === "TempF") {
echo 'Temp: ' . $field->attributes()->value . "<br>";
}
}
}
Output
<h2>Server Temperature</h2>Temp: 76.55<br>
See a Php demo
Or if you want to loop all the values of field, you can use xpath:
echo '<h2>Server Temperature</h2>';
foreach ($xml->xpath('/devices/device/field[#key="TempF"]/#value') as $value) {
echo 'Temp: ' . $value . "<br>";
}
Output
<h2>Server Temperature</h2>Temp: 76.55<br>
See another Php demo
I am trying to display attributes foreach global_ivr_variable:
$xml = '
<response method="switchvox.ivr.globalVariables.getList">
<result>
<global_ivr_variables>
<global_ivr_variable id="1" name="cid_name" value="Smith" />
<global_ivr_variable id="2" name="Q_ID_Global" value="COS" />
</global_ivr_variables>
</result>
</response>
';
$sxml = simplexml_load_string($xml);
foreach($sxml->result->global_ivr_variables->global_ivr_variable->attributes() as $a => $b)
{
echo $a .'=' . $b . "<br>";
}
All I get is the attributes of the first node:
id="1"
name="cid_name"
value="Smith"
I've also tried the following, which gives me no values at all...
foreach($sxml->result->global_ivr_variables as $xvar)
{
$a = $xvar->global_ivr_variable->id;
$b = $xvar->global_ivr_variable->name;
$c = $xvar->global_ivr_variable->value;
echo 'a='.$a.', b='.$b.', c='.$c.'<br>';
}
a=, b=, c=
Thank you all who step up to help the needy!
You almost had it but you need to iterate through each of the <global_ivr_variable> elements and then pull out the attributes:
foreach($sxml->result->global_ivr_variables->global_ivr_variable as $variable)
{
foreach($variable->attributes() as $a => $b)
{
echo $a .'=' . $b . "<br>";
}
}
If you make use of PHP variables, those problems normally easily disappear because your code is more readable.
Additionally you can access the attributes in SimpleXML via array-notation:
$variables = $sxml->result->global_ivr_variables->global_ivr_variable;
foreach ($variables as $variable)
{
printf("%s = %s\n", $variable['name'], $variable['value']);
}
This gives the following output:
cid_name = Smith
Q_ID_Global = COS
As you know upfront for which attributes you're looking for, your code is much more clear and stable by using those names.
However, if you're looking for just all attributes of the global_ivr_variable elements, then it's easier to iterate over them with XPath:
$allAttributes = $sxml->xpath('//global_ivr_variable/#*');
foreach ($allAttributes as $attribute) {
printf("%s = %s\n", $attribute->getName(), $attribute);
}
This then gives the following output:
id = 1
name = cid_name
value = Smith
id = 2
name = Q_ID_Global
value = COS
Here is the full code-example:
$xml = <<<XML
<response method="switchvox.ivr.globalVariables.getList">
<result>
<global_ivr_variables>
<global_ivr_variable id="1" name="cid_name" value="Smith" />
<global_ivr_variable id="2" name="Q_ID_Global" value="COS" />
</global_ivr_variables>
</result>
</response>
XML;
$sxml = simplexml_load_string($xml);
$variables = $sxml->result->global_ivr_variables->global_ivr_variable;
foreach ($variables as $variable)
{
printf("%s = %s\n", $variable['name'], $variable['value']);
}
echo "----\n";
$allAttributes = $sxml->xpath('//global_ivr_variable/#*');
foreach ($allAttributes as $attribute) {
printf("%s = %s\n", $attribute->getName(), $attribute);
}
here is my xml file note.xml file
<?xml version="1.0" encoding="ISO-8859-1"?>
<agents>
<agent>
<id>1</id>
<image> img/primary-nav-logo.png</image>
<name>Tommy Jenkin</name>
<company>CJenkins Insurance</company>
<street>Insurance150 S State Stree</street>
<city>Linkend</city>
<phone>(773) 561-4331</phone>
</agent>
<agent>
<id>2</id>
<image> img/primary-nav-logo.png</image>
<name>Tommy Jenkin</name>
<company>CJenkins Insurance</company>
<street>Insurance150 S State Stree</street>
<city>Linkend</city>
<phone>(773) 561-4331</phone>
</agent>
</agents>
and i have to print xml record of id 1 and i have write code in php like this
<?php
$xml = simplexml_load_file("note.xml") or die("Error: Cannot create object");
foreach($xml->xpath('//agent') as $item) {
$row = simplexml_load_string($item->asXML());
$v = $row->xpath('//id[. ="1"]');
if($v[0]){
print $item->id;
print $item->image;
print $item->name;
print $item->company;
print $item->street;
print $item->city;
print $item->phone;
}
else{
echo 'No records';
}
?>
please suggest me where i am wrong
You do not need to call $item->asXML() since $item is already a SimpleXML object. And you don't have to loop over your array since you can query the necessary agent directly. Try this:
<?php
$xml = simplexml_load_file("note.xml") or die("Error: Cannot create object");
$agent = $xml->xpath('//agent[id=1]');
if (!empty($agent)) {
$item = $agent[0];
print $item->id;
print $item->image;
print $item->name;
print $item->company;
print $item->street;
print $item->city;
print $item->phone;
} else {
echo 'No records';
}
First of all, you are missing the closing bracket of foreach loop.
Second, you can do this with xPath itself.
Look at this code:
<pre><?php
$xml = simplexml_load_file("note.xml") or die("Error: Cannot create object");
$item = $xml->xpath('//agents/agent[id=1]')[0];
if($item!=null){
print_r($item);
}else{
echo "No Records";
}
?></pre>
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>";
}
}
}
I have an xml file that has different named nodes and multi level child nodes (that are different between each node.) How should I access the data? Will it require many nested for loops?
Here is a sample of the xml code:
<start_info>
<info tabindex="1">
<infonumber>1</infonumber>
<trees>green</trees>
</info>
</start_info>
<people>
<pe>
<people_ages>
<range number="1">
<age value="1">1</age>
<age value="2">2</age>
</range>
</people_ages>
</pe>
</people>
Here is my code so far:
$xml = simplexml_load_file("file.xml");
echo $xml->getName() . "start_info";
foreach($xml->children() as $child)
{
echo $child->getName() . ": " . $child . "<br />";
}
Here is some example code that I hope can point you in the right direction. Essentially, it is walking the DOMDocument echoing the element name and values. Note that the whitespace between the elements is significant, so for the purposes of the demo, the XML is compacted. You may find a similar issue loading from a file, so if you are not getting the expected output you might need to strip whitespace nodes.
You could replace the //root/* with a different XPath for example //people if you only wanted the <people> elements.
<?php
$xml = <<<XML
<root><start_info><info tabindex="1"><infonumber>1</infonumber><trees>green</trees></info></start_info>
<people><pe><people_ages><range number="1"><age value="1">1</age><age value="2">2</age></range></people_ages></pe></people>
</root>
XML;
$dom = new DOMDocument();
$dom->recover = true;
$dom->loadXML($xml);
$xpath = new DOMXPath($dom);
$nodelist = $xpath->query('//root/*');
foreach ($nodelist as $node) {
echo "\n$node->tagName";
getData($node);
}
function getData($node) {
foreach ($node->childNodes as $child) {
if ($child->nodeType == XML_ELEMENT_NODE) {
echo ($child->tagName === '' ? '' : "\n").$child->tagName;
}
if ($child->nodeType == XML_TEXT_NODE) {
echo '->'.$child->nodeValue;
}
if ($child->hasChildNodes()) {
getData($child); // recursive call
}
}
}
?>
check this
$xml_file = 'file.xml';
$xmlobj = simplexml_load_file($xml_file);
echo $xmlobj->getName() . 'start_info<br />';
foreach($xmlobj->children() as $childs) {
echo $childs->getName(). ': '. '<br />';
if($childs->count()>1) {
foreach($childs as $child) {
echo $child->getName(). ': '. $child. '<br />';
}
}
}