php 使用 SimpleXML 解析带有命名空间的 XML
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/595946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parse XML with Namespace using SimpleXML
提问by user38968
I have this as xml:
我有这个作为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?
如何遍历所有 event:event 节点并显示,例如,所有 event:SessionKey?
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'));
}
回答by ax.
it does work without registerXPathNamespaceand the full namespace prefix in the xpath queries:
它确实registerXPathNamespace在 xpath 查询中没有和完整的命名空间前缀的情况下工作:
$xml = new SimpleXMLElement($r);
foreach($xml->xpath('//event:event') as $event) {
var_export($event->xpath('event:sessionKey'));
}
回答by mcrumley
You have to register the namespace for each simpleXMLElement object you use.
您必须为您使用的每个 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'));
}
The namespace should also be declared somewhere in the xml file.
命名空间也应该在 xml 文件中的某处声明。
<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.
描述的方法 ax 也有效。如果您知道 xml 文件将始终使用相同的前缀,则可以跳过 registerXPathNamespace。
回答by ewwink
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;
}
回答by Cameron
Having worked a lot with simplexml, this is how I do it.
使用 simplexml 做了很多工作,这就是我的做法。
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 childrenfunction:
是将 TRUE 作为第二个参数发送给children函数:
$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();
回答by Asad Saeeduddin
Another approach is to use SimpleXMLfor parsing and DOMDocumentfor manipulation/access, which bypasses namespacing issues altogether:
另一种方法是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;
}
回答by Raf
Using registerXPathNamespaceand then calling xpathdidn'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
使用registerXPathNamespace然后调用xpath实际上对我不起作用。我不得不使用这篇很棒的文章中提供的解决方案: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
在几分钟内学习 QB

