views:

41

answers:

3

I have a simple xml below:

<?xml version="1.0" encoding="utf-8"?>
<catalogue>
  <category name="textbook" id="100" parent="books">
    <product id="20000">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications
      with XML.</description>
    </product>
    <product id="20001">
      <author>Gambardellas, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications
      with XML.</description>
    </product>
  </category>
  <category name="fiction" id="101" parent="books">
    <product id="2001">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <type>Fiction</type>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, an evil sorceress,                  and her own childhood to become queen
      of the world.</description>
    </product>
  </category>
</catalogue>

I am using php simplexml library to parse it as follows: (note there are two category nodes. The first category contains two 'product' children. My aim is to get an array that contains those two children of first 'category'

$xml = simplexml_load_file($xml_file) or die ("unable to load XML File!".$xml_file);

//for each product, print out info
$cat = array();
foreach($xml->category as $category)
{
    if($category['id'] == 100)
    {
        $cat = $category;       
        break;
    }
}
$prod_arr = $category->product;

Here is the problem. I am expecting an array with two products children but its only returning one product. What am I doing wrong or is this a php bug? Please help!

+1  A: 

For start, your XML file is not well defined. You should probably start and end it with <categories> tag.

Replace the last assignment with the following:

$prod_array = array();
foreach ($cat->product as $p) {
    $prod_array[] = $p;
}
Anax
A: 
$cat = array();
foreach ($xml->category as $category)
{
    $attributes = $category->attributes();
    if(isset($attributes['id']) && $attributes['id'] == 100)
    {
        $cat = $category;
        break;
    }
}
OcuS
Do not ever forget to validate a XML file before blaming your code. This is quite simple, just open your file with firefox (or try the xmllint command under Linux), it will show you where errors are if any.
OcuS
I fixed my code according to your edit :)
OcuS
+2  A: 

You can use SimpleXMLElement::xpath() to get all product elements that are children of a specific category element. E.g.

 // $catalogue is your $xml
 $products = $catalogue->xpath('category[@id="100"]/product');
 foreach($products as $p) {
   echo $p['id'], ' ', $p->title, "\n";
 }

prints

20000 XML Developer's Guide
20001 XML Developer's Guide
VolkerK