使用多个命名空间解析 XML

所以我想解析这个 XML:

So I wanted to parse this XML:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <requestContactResponse xmlns="http://webservice.foo.com">
      <requestContactReturn>
        <errorCode xsi:nil="true"/>
        <errorDesc xsi:nil="true"/>
        <id>744</id>
      </requestContactReturn>
    </requestContactResponse>
  </soapenv:Body>
</soapenv:Envelope>

具体我想获取标签<id>

这是我尝试过的:

$dom = new DOMDocument;
$dom->loadXML($xml);
$dom->children('soapenv', true)->Envelope->children('soapenv', true)->Body->children()->requestContactResponse->requestContactReturn->id;

但我收到此错误消息:

PHP 致命错误:调用未定义的方法 DOMDocument::children()

PHP Fatal error: Call to undefined method DOMDocument::children()

我也尝试过使用 simpleXML:

I've also tried to use simpleXML:

$sxe = new SimpleXMLElement($xml);
$sxe->children('soapenv', true)->Envelope->children('soapenv', true)->Body->children()->requestContactResponse->requestContactReturn->id;

但我收到了另一个错误消息:

But I get this other error message:

PHP 致命错误:在非对象上调用成员函数 children()

PHP Fatal error: Call to a member function children() on a non-object

我尝试过的最后一个解决方案:

Last solution I've tried:

$sxe = new SimpleXMLElement($xml);
$elements = $sxe->children("soapenv", true)->Body->requestContactResponse->requestContactReturn;

foreach($elements as $element) {
    echo "|-$element->id-|";
}

这次的错误信息是:

Invalid argument supplied for foreach() 

有什么建议吗?

推荐答案

这里没有记录的事实是,当你选择一个带有 ->children 的命名空间时,它保留在对后代节点的影响.

The poorly documented fact in play here is that when you select a namespace with ->children, it remains in effect for descendent nodes.

因此,当您询问 $sxe->children("soapenv", true)->Body->requestContactResponse 时,SimpleXML 假定您仍在谈论 "soapenv" 命名空间,因此正在寻找不存在的元素 .

So when you ask for $sxe->children("soapenv", true)->Body->requestContactResponse, SimpleXML assumes you are still talking about the "soapenv" namespace, so is looking for the element <soapenv:requestContactResponse>, which doesn't exist.

要切换回默认命名空间,您需要再次调用 ->children,并使用 NULL 命名空间:

To switch back to the default namespace, you need to call ->children again, with a NULL namespace:

$sx->children("soapenv", true)->Body->children(NULL)->requestContactResponse->requestContactReturn->id

相关文章