我将此作为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'));
}
答案 0 :(得分:28)
它在没有registerXPathNamespace
且xpath查询中的完整名称空间前缀的情况下工作:
$xml = new SimpleXMLElement($r);
foreach($xml->xpath('//event:event') as $event) {
var_export($event->xpath('event:sessionKey'));
}
答案 1 :(得分:21)
您必须为您使用的每个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。
答案 2 :(得分:13)
这里替代方案对我有用。
$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;
}
答案 3 :(得分:10)
使用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>
将true作为第二个参数发送到子函数:
$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();
答案 4 :(得分:6)
另一种方法是使用SimpleXML
进行解析,使用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;
}
答案 5 :(得分:4)
使用registerXPathNamespace
然后调用xpath
对我来说实际上并不起作用。
我不得不采用这篇伟大帖子中提供的解决方案: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
答案 6 :(得分:-4)
我可能错了,但我认为使用SimpleXMLElement
可以正确解析带有像SOAP这样的冒号符号的XML。
我确信有更优雅的方法可以做到这一点,但我通常使用file_get_contents()
将文件内容读入变量,然后替换/删除冒号,然后将其发送到SimpleXMLElement
。