I am trying to parse an XML file with php SimpleXML and xpath and having problems getting the paths right and accessing attribute values. Any help appreciated.
Here is my xml file:-
<message:MessageGroup xmlns="http://mynamespace.com">
<Book>
<BookKey>
<Value concept="TITLE" value="Gone Girl"/>
<Value concept="AUTHOR" value="Gillian Flynn"/>
</BookKey>
<Sales>
<Month>Jan</Month>
<Number value="20"/>
</Sales>
<Sales>
<Month>Feb</Month>
<Number value="15"/>
</Sales>
<Sales>
<Month>Mar</Month>
<Number value="30"/>
</Sales>
</Book>
<Book>
<BookKey>
<Value concept="TITLE" value="Inferno"/>
<Value concept="AUTHOR" value="Dan Brown"/>
</BookKey>
<Sales>
<Month>Jan</Month>
<Number value="10"/>
</Sales>
<Sales>
<Month>Feb</Month>
<Number value="15"/>
</Sales>
<Sales>
<Month>Mar</Month>
<Number value="3"/>
</Sales>
</Book>
</message:MessageGroup>
I need to parse this to get the following output:-
Gone Girl,Gillian Flynn,Jan,20
Gone Girl,Gillian Flynn,Feb,15
Gone Girl,Gillian Flynn,Mar30
Inferno,Dan Brown,Jan,10
Inferno,Dan Brown,Feb,15
Inferno,Dan Brown,Mar,3
I have written the following code:-
<?php
$xmlfile = 'Books.xml';
$xml = simplexml_load_file($xmlfile);
$namespace = 'http://mynamespace.com';
$xml->registerXPathNamespace('ns',$namespace);
$books = $xml->xpath('//ns:Book');
//loop through each book -
foreach($books as $book) {
$values = $xml->xpath('ns:BookKey/Value');
$bookkeys= array();
//loop through each Book's BookKey Values and push them to array -
foreach($values as $value){
array_push($bookkeys, $value->attributes()->value);
}
$sales = $xml->xpath('ns:Sales');
//loop through each Book's Sales and write out Month and Number value after the book key values -
foreach($sales as $sale){
foreach($bookkeys as $bk){
echo $bk.",";
}
echo $sale->Month;
echo ",";
echo $sale->Number->attributes()->value;
echo "\n";
}
}
?>
From a var_dump, the $books array appears to be ok; $values and $sales are empty arrays though, so clearly the paths are not right. I have tried leaving out the namespace but still get an empty array; I want to avoid pulling out all the instances of values and sales in the file as opposed to just the ones for each particular book.
message?SimpleXMLElement::children()with the namespace paramter(s) set. Same applies toSimpleXMLElement::attributes(), you also need to pass the namespace, it is not inherited from the element node.