GDP GDP - 4 years ago 109
PHP Question

How to get values from mix of namespace and non-namespace XML with

Given the XML and related PHP, below how can I get the namespaced values in the same way that I'm able to get the non-namespaced values? I've been referring to a number of other SE QAs about this, but can't seem to get it right. An help is appreciated. :)

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:psg="http://b3000.example.net:3000/psg_namespace/">
<channel>
<title>Example</title>
<description>example stuff</description>
<item>
<psg:eventId>406589</psg:eventId>
<psg:duration>3482</psg:duration>
</item>
</channel>
</rss>

$xml = new SimpleXMLElement($source, null, true);
foreach($xml->channel->item as $entry){
echo $entry->title; // This works
echo $entry->description; // This works
echo $entry->item->duration // Pseudo of what I need
}


How to get Duration? My attempts with variations such as this have failed

$namespaces = $item->getNameSpaces(true);
$psg = $item->children($namespaces['psg']);


Update

While it wasn't the answer I was actually looking for, I have to accept the first answer that got me trying things leading to the actual problem - "operator error"! This DOES work....my problem was in trying to figure it out, I was debugging with
echo print_r($psg, true)
. That was showing the result as a SimpleXmlObject, which then got me chasing how to get those properties - All I had to do was assign the property instead of echoing it.

foreach($xml->channel->item as $entry){
$psg = $item->children($ns['psg']);
$title = (string) $item->title;
$duration = (string) $psg->duration;
}

Answer Source

One way to achieve this is to use a combination of XPath with namespaces:

$xml = new SimpleXMLElement($source, null, true);
$xml->registerXPathNamespace('psg', 'http://b3000.example.net:3000/psg_namespace/');

foreach ($xml->xpath('//item/psg:duration') as $duration) {
    echo $duration, PHP_EOL;
}

If you don't want to declare the namespace literally, you can retrieve it from the document and add it/them dynamically:

foreach ($xml->getDocNamespaces() as $key => $namespace) {
    $xml->registerXPathNamespace($key, $namespace);
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download