2

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.

Bendihossan
  • 2,407
  • 5
  • 22
  • 25

3 Answers3

3

You shouldn't use an XML parser to read rdf/xml since it doesn't understand the encoding of writing RDF triples into XML; there are multiple ways to do write down one of the terms like cd:artist. It's like using regexes over JSON data - it might work but it's not going to catch all cases. Using an XML approach, you'll end up with mis-understandings. I recommend you use a parser from https://github.com/semsol/arc2

The only way the XML approach would work is if the generated XML is guaranteed to always written with the same template. This is the case for XMP document metadata, for example.

dajobe
  • 4,938
  • 35
  • 41
  • 2
    This. Using a ready-made RDF/XML parser like arc2 also has the advantage that you can parse other RDF syntaxes like [Turtle](http://www.w3.org/TR/turtle/) or [RDFa](http://www.w3.org/TR/xhtml-rdfa-primer/) using the same API with minimal or no changes to your code. – cygri Apr 09 '12 at 11:11
  • Good answer but my needs for this are quite small at the moment so simplicity matters more. Will keep arc2 in mind for the future though. Thanks! – Bendihossan Apr 09 '12 at 15:03
  • Bendihossan, if you want simplicity, why do you introduce an XML API into the picture? Your case is trivially solved with a regular expression. When you introduce an XML tool in the picture, you're making it as complicated as if you used a native RDF tool, with the difference that your XML tool won't be able to treat the more complex cases. – Antoine Zimmermann Apr 12 '12 at 07:26
  • Antoine: I'm new to RDF and I'm still learning about RDF and ontologies. For that reason I'm keeping things simple to begin with until I understand it more and I can use it in a more meaningful way. – Bendihossan Apr 14 '12 at 00:46
1

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.

Tom Imrei
  • 1,514
  • 12
  • 16
  • If I parse Bendihossan's RDF/XML document and serialise it back to RDF/XML, I may obtain a different XML structure such as: `` The same XPath query would not work, yet the RDF graph is exactly the same. – Antoine Zimmermann Apr 12 '12 at 07:30
0

For what is worth, here is a SPARQL query that can give you the properties in the dc namespace, no matter how the file is formatted (contrary to Tamas Imrei's XPath query which only works if the file is formatted exactly like your example):

SELECT ?terms WHERE {
   ?s  ?terms  ?o .
   FILTER (regex(str(?term),"http://www.recshop.fake/cd#"))
}

This is also independent of the namespace prefix you use.

Antoine Zimmermann
  • 5,314
  • 18
  • 36