Php 迭代SimpleXml xpath结果
我使用SimpleXMLElement读取从远程服务器返回的xml。 然后使用xpath解析结果,如下所示:Php 迭代SimpleXml xpath结果,php,xml,xpath,simplexml,Php,Xml,Xpath,Simplexml,我使用SimpleXMLElement读取从远程服务器返回的xml。 然后使用xpath解析结果,如下所示: $result = <<<XML <DataImport2Result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.xxx.xxx/Services/DataImport2"&
$result = <<<XML
<DataImport2Result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.xxx.xxx/Services/DataImport2">
<Number />
<Blocks>
<Block>
<Code>Fbf</Code>
<Fields>
<Field>
<Code>FinnsIFbf</Code>
<Value>1</Value>
</Field>
</Fields>
</Block>
</Blocks>
</DataImport2Result>
XML;
$xml = new SimpleXMLElement($result);
$xml->registerXPathNamespace("data", array_pop($xml->getNamespaces()));
foreach($xml->xpath("//data:Code[.='Fbf']/..") as $block) {
foreach($block[0]->Fields->Field as $field) {
echo "Code: ". $field->Code ."\n"; // SHould return FinnsIFbf
}
}
$result是一个包含SimpleXMLElement对象的数组。当尝试将$block[0]->字段(SimpleXMLElement对象)用作数组时,会发生实际错误。结果就在那里。问题在于迭代。这在PHP5.3.2中运行得很好,但在运行5.1.6的服务器上,它失败了:
致命错误:在增量后/增量前/减量中用作数组的对象必须通过引用返回值 在不升级服务器版本的情况下,最简单的解决方法是什么(服务器管理员认为更新版本“不稳定”)
一种解决方案可能是,如果我可以让xpath返回第一个$result中的字段,那么我就不必迭代
$block[0]->Fields->Field
,但我无法生成这样的xpath表达式。这可能是因为$block不是数组。您应该使用var\u dump
或print\u r
来确认这一点,然后在代码中使用is\u array
来确保它是一个数组
如果SimpleXML找到具有相同名称的多个元素,它将返回一个对象数组。如果它找到单个元素,则只返回该元素,而不返回包含单个元素的数组。因此,当您需要多个元素时,始终必须为只有一个元素的情况编写例外情况代码。正如Sjoerd的回答中提到的,
$block
不是数组。返回一个对象数组,每个对象表示一个元素。因此,基本上,您必须将$block[0]
替换为$block
,因为它已经表示您要查找的块
此外,我还重写了XPath表达式。因为您正在寻找一个
元素,所以这就是您应该瞄准的目标。关于
的东西是一个谓词,所以它应该放在括号内。当然,在您的情况下,结果是相同的,但最好使用语义正确的表达式,这有助于您在阅读代码(或者其他人必须维护代码)时更清楚地了解后面发生的事情
更新 我没有注意到您说过您只对
元素感兴趣。在这种情况下,您可以直接通过XPath获得它:(记住它们都在数据名称空间中)
请发布一个简短的、可复制的代码片段。您可能访问的元素不正确。另外,错误消息与您发布的内容无关。@Josh Davis:我已经更新了代码,提供了一个开箱即用的示例,并且给出了相同的错误。Thx,我稍后再看一看。我不确定“它返回一个对象数组”是什么意思。xpath()总是返回一个数组,通过对象表示法访问元素(例如,
$xml->Blocks
)始终返回SimpleXMLElement,无论它代表多少个元素,您可以使用带有数字索引的数组表示法,按照元素在文档中的显示顺序访问元素。在该示例中,您可以通过$xml->Blocks[0]->block[0]
访问该块,即使每个块只有一个。不过,较旧版本的SimpleXML在某些情况下不起作用。
foreach ($xml->xpath('//data:Block[data:Code="Fbf"]') as $block) {
foreach ($block->Fields->Field as $field) {
echo "Code: ". $field->Code ."\n"; // SHould return FinnsIFbf
}
}
foreach ($xml->xpath('//data:Block[data:Code="Fbf"]/data:Fields/data:Field') as $field) {
echo "Code: ". $field->Code ."\n"; // SHould return FinnsIFbf
}