简体   繁体   English

"使用 SimpleXML 使用命名空间解析 XML [重复]"

[英]Parse XML with Namespace using SimpleXML [duplicate]

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><\/code><\/pre>

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')); }<\/code><\/pre>"

it does work without registerXPathNamespace and 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'));
}

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.描述的方法 ax 也有效。 You can skip the registerXPathNamespace if you know the xml file will always use the same prefix.如果您知道 xml 文件将始终使用相同的前缀,则可以跳过 registerXPathNamespace。

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

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 children function:是将 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();

Another approach is to use SimpleXML<\/code> for parsing and DOMDocument<\/code> for manipulation\/access, which bypasses namespacing issues altogether:另一种方法是使用SimpleXML<\/code>进行解析,使用DOMDocument<\/code>进行操作\/访问,这完全绕过了命名空间问题:

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

Using registerXPathNamespace<\/code> and then calling xpath<\/code> didn't actually work for me.使用registerXPathNamespace<\/code>然后调用xpath<\/code>实际上对我不起作用。 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<\/a>我不得不使用这篇很棒的帖子中提供的解决方案: http<\/a> :\/\/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;

I could be wrong but I don't think XML with the colon symbol like SOAP can be parsed properly using SimpleXMLElement . 我可能是错的,但是我不认为可以使用SimpleXMLElement正确解析带有冒号(如SOAP)的XML。

I'm sure there's a more elegant way of doing this but I usually read the file contents into a variable using file_get_contents() then replace/remove the colons then send it to SimpleXMLElement . 我确定有一种更优雅的方法,但是我通常使用file_get_contents()将文件内容读入变量,然后替换/删除冒号,然后将其发送到SimpleXMLElement

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM