在 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 对象,因此命名空间注册只需进行一次。
我发布了另一个问题,我的错误是不完整。 我有一个带有多个命名空间的 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 对象,因此命名空间注册只需进行一次。