Search code examples
phpxmlrdfsemantic-websemantic-markup

Parsing nested XML/RDF namespace elements in PHP with SimpleXML


Given the XML/RDF example below taken from the W3C website, how can I access the values in the "cd" namespace?

<?xml version="1.0"?>

<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cd="http://www.recshop.fake/cd#">

<rdf:Description
rdf:about="http://www.recshop.fake/cd/Empire Burlesque">
  <cd:artist>Bob Dylan</cd:artist>
  <cd:country>USA</cd:country>
  <cd:company>Columbia</cd:company>
  <cd:price>10.90</cd:price>
  <cd:year>1985</cd:year>
</rdf:Description>

</rdf:RDF> 

I've tried doing the following:

$XML = new SimpleXMLElement($rawXML); // Assume $rawXML is the quoted XML/RDF above
foreach($xml as $entry){
    $cd = $entry->children('http://www.recshop.fake/cd#');
    echo $cd->artist;
    echo $cd->$country;
    ...
}

and I've also tried doing:

$XML = new SimpleXMLElement($rawXML); // Assume $rawXML is the quoted XML/RDF above
foreach($xml as $entry){
    $cd = $entry->children('http://www.recshop.fake/cd#');
    $rdf = $entry->children('http://www.w3.org/1999/02/22-rdf-syntax-ns#');
    echo $rdf->$cd->artist;
    echo $rdf->$cd->$country;
    ...
}

Also, in PHP is it necessary to do anything different if instead of declaring xmlns:cd="http://www.recshop.fake/cd#" it were xmlns="http://www.recshop.fake/cd#" and the "cd" namespace was removed from <cd:artist>, etc.


Solution

  • You can use xpath, first you need to register the namespaces. Try this:

    $xml = new SimpleXMLElement($rawXML);
    
    $xml->registerXPathNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
    $xml->registerXPathNamespace('cd', 'http://www.recshop.fake/cd#');
    
    $cd = $simple->xpath('rdf:Description/cd:*');
    

    $cd will be an array of SimpleXMLElements.