使用SimpleXML使用名称空间parsingXML

我有这个作为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> 

我怎样才能循环所有的事件:事件节点和显示,例如,所有的事件:SessionKey的?

这不起作用:

 $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')); } 

它在xpath查询中没有registerXPathNamespace和完整的命名空间前缀:

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

你必须注册你使用的每个simpleXMLElement对象的名字空间。

 $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')); } 

命名空间也应该在xml文件中的某个地方声明。

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

所描述的方法也起作用。 如果您知道xml文件将始终使用相同的前缀,则可以跳过registerXPathNamespace。

这里替代我的工作。

 $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; } 

另一种方法是使用SimpleXML进行parsing,并使用DOMDocument进行操作/访问,从而绕过命名空间问题:

 $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; } 

使用registerXPathNamespace ,然后调用xpath实际上并没有为我工作。 我不得不采取在这个伟大的职位提供的解决scheme: http : //blog.preinheimer.com/index.php?/archives/172-SimpleXML,-Namespaces-Hair-loss.html

所以在你的情况下,这个:

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

会输出:

在几分钟内学习QB

与simplexml工作了很多,这是我如何做到这一点。

如果你已经有一个元素,只是想要得到它不同的命名空间的孩子,这个魔术就是这样的结构:

 <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> 

是发送真正的第二个参数给子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(); 

我可能是错的,但是我不认为使用SimpleXMLElement可以正确parsing带有像SOAP这样的冒号符号的XML。

我确信有一个更优雅的方式做到这一点,但我通常使用file_get_contents()将文件内容读入一个variables,然后replace/移除冒号,然后将其发送到SimpleXMLElement