在 PHP 中从具有多个命名空间的 XML 内容中检索值数组

Retrieving an array of values from an XML content with multiple namespaces in PHP

我发布了另一个问题,我的错误是不完整。 我有一个带有多个命名空间的 XML,但我需要访问 foreach 中的值。

我的 XML 数组是:

<ArrayOfSession xmlns:i='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://schemas.datacontract.org/2004/07/Vista.Online.BackOffice.Api.Models.V1'> 
<Session>
  <AreComplimentariesAllowed>true</AreComplimentariesAllowed>
  <Attributes xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <d3p1:string>0000000009</d3p1:string>
    <d3p1:string>0000000011</d3p1:string>
  </Attributes>
</Session>
</ArrayOfSession>

另一位用户帮助了我:

有了这个答案,我尝试了一些变体。这是我目前使用的,但无法正常工作:

$xml->registerXPathNamespace('i', 'http://www.w3.org/2001/XMLSchema-instance');
$xml->registerXPathNamespace('j', 'http://schemas.datacontract.org/2004/07/Vista.Online.BackOffice.Api.Models.V1');
$xml->registerXPathNamespace('ns', 'http://schemas.microsoft.com/2003/10/Serialization/Arrays');

foreach($xml->xpath('//ns:d3p1') as $header){
    var_export($header->xpath('//Attributes/ns:string'));
}

我也试过:

foreach($xml->xpath('//ns:d3p1') as $header){
        var_export($header->xpath('//ns:string'));
    }

这难倒我了!

在其余代码的当前工作版本中,我正在检索元素:

foreach($xml->Session as $event){
    // Do Something with $event->AreComplimentariesAllowed
}

这很好用,但我就是无法访问那些 Attributes 元素。

一如既往的感谢。

在调用 xpath() 之前,您必须在每个 SimpleXMLElement 上注册命名空间。您将它们注册到 $xml 变量,而不是 $header.

您的 XML 也有默认名称空间。您确实为它注册了前缀 j,但您没有在表达式中使用该前缀。最后这里没有元素 d3p1。这只是文档中的命名空间前缀。

因此要迭代 Session 元素,然后迭代 Attributes

中的 string
$sessions = new SimpleXMLElement($xml);
$sessions->registerXPathNamespace(
  'j', 
  'http://schemas.datacontract.org/2004/07/Vista.Online.BackOffice.Api.Models.V1'
);

foreach($sessions->xpath('//j:Session') as $session) {
  $session->registerXPathNamespace(
    'j', 
    'http://schemas.datacontract.org/2004/07/Vista.Online.BackOffice.Api.Models.V1'
  );
  $session->registerXPathNamespace(
    'ns', 
    'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
  );
  var_export($session->xpath('.//j:Attributes/ns:string'));
}

在 DOM 中看起来不一样:

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace(
  'j', 
  'http://schemas.datacontract.org/2004/07/Vista.Online.BackOffice.Api.Models.V1'
);
$xpath->registerNamespace(
  'ns', 
  'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
);

foreach ($xpath->evaluate('//j:Session') as $session) {
  var_export(
    iterator_to_array($xpath->evaluate('.//j:Attributes/ns:string', $session))
  );
}

它有一个专用的 Xpath 对象,因此命名空间注册只需进行一次。