Parse XML with Namespace using SimpleXML

PhpXmlNamespacesSimplexml

Php Problem Overview


I have this as xml:

<root xmlns:event="http://www.webex.com/schemas/2002/06/service/event">
    <event:event>
        <event:sessionKey></event:sessionKey>
        <event:sessionName>Learn QB in Minutes</event:sessionName>
        <event:sessionType>9</event:sessionType>
        <event:hostWebExID></event:hostWebExID>
        <event:startDate>02/12/2009</event:startDate>
        <event:endDate>02/12/2009</event:endDate>
        <event:timeZoneID>11</event:timeZoneID>
        <event:duration>30</event:duration>
        <event:description></event:description>
        <event:status>NOT_INPROGRESS</event:status>
        <event:panelists></event:panelists>
        <event:listStatus>PUBLIC</event:listStatus>
    </event:event>
    ...
</root>

How can I loop through all of the event:event nodes and display, for example, all of the event:SessionKey's?

This does not work:

$xml = new SimpleXMLElement($r);
$xml->registerXPathNamespace('e', 'http://www.webex.com/schemas/2002/06/service/event');

foreach($xml->xpath('//e:event') as $event) {
 var_export($event->xpath('//e:sessionKey'));
}

Php Solutions


Solution 1 - Php

it does work without registerXPathNamespace and the full namespace prefix in the xpath queries:

$xml = new SimpleXMLElement($r);

foreach($xml->xpath('//event:event') as $event) {
 var_export($event->xpath('event:sessionKey'));
}

Solution 2 - Php

You have to register the namespace for each simpleXMLElement object you use.

$xml = new SimpleXMLElement($r);
$xml->registerXPathNamespace('e', 'http://www.webex.com/schemas/2002/06/service/event');

foreach($xml->xpath('//e:event') as $event) {
	$event->registerXPathNamespace('e', 'http://www.webex.com/schemas/2002/06/service/event');
	var_export($event->xpath('//e:sessionKey'));
}

The namespace should also be declared somewhere in the xml file.

<event:event xmlns:event="http://www.webex.com/schemas/2002/06/service/event">
...

The method ax described works too. You can skip the registerXPathNamespace if you know the xml file will always use the same prefix.

Solution 3 - Php

here alternative that worked for me.

$xml = simplexml_load_string($r);
$ns = $xml->getNamespaces(true);

foreach ($xml->children($ns['event'])->event as $skey) {
	$sessionKey = $skey->children($ns['event'])->sessionKey;
	echo $sessionKey;
}

Solution 4 - Php

Having worked a lot with simplexml, this is how I do it.

The magic trick if you already have an element and just want to get it's different namespaced children, say for a structure like this:

<entry>
<title type="text">My test entry</title>
<gd:when startTime="2017-02-26T02:00:00Z" endTime="2017-02-26T03:00:00Z"/>
<gc:notes type="string">A type</gc:notes>
</entry>

Is to send TRUE as the second parameter to the children function:

  $title = (string) $entry->title;
  $gd = $entry->children('gd', TRUE);
  $attrs = $gd->when->attributes();
  $startTime = (string) $attrs->startTime;
  $gc = $entry->children('gc', TRUE);
  $notes = (string) $gc->notes();

Solution 5 - Php

Another approach is to use SimpleXML for parsing and DOMDocument for manipulation/access, which bypasses namespacing issues altogether:

$xml = new SimpleXMLElement($r);
$xml = dom_import_simplexml($xml);
$nodelist= $xml->getElementsByTagName('event');  
for($i = 0; $i < $nodelist->length; $i++) {
    $sessions = $nodelist->item($i)->getElementsByTagName('sessionKey');
    echo $sessions->item(0)->nodeValue;
}

Solution 6 - Php

Using registerXPathNamespace and then calling xpath didn't actually work for me. I had to go with the solution provided in this great post : http://blog.preinheimer.com/index.php?/archives/172-SimpleXML,-Namespaces-Hair-loss.html

So in your case, this :

echo $xml->children('http://www.webex.com/schemas/2002/06/service/event')->sessionName;

Will output:

> Learn QB in Minutes

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser38968View Question on Stackoverflow
Solution 1 - Phpax.View Answer on Stackoverflow
Solution 2 - PhpmcrumleyView Answer on Stackoverflow
Solution 3 - PhpewwinkView Answer on Stackoverflow
Solution 4 - PhpCameronView Answer on Stackoverflow
Solution 5 - PhpAsad SaeeduddinView Answer on Stackoverflow
Solution 6 - PhpRafView Answer on Stackoverflow