代码之家  ›  专栏  ›  技术社区  ›  baloo

迭代SimpleXml xpath结果

  •  2
  • baloo  · 技术社区  · 15 年前

    我使用simplexmlement读取从远程服务器返回的xml。

    $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是一个包含simplexmlement对象的数组。尝试使用$block[0]->时发生实际错误;字段(SimpleXMLElement对象)作为数组。所以结果是有的。迭代才是问题所在。
    这在PHP5.3.2中运行得很好,但在运行5.1.6的服务器上失败:
    致命错误:在后/前递增/递减中用作数组的对象必须通过引用返回值

    在不升级服务器版本的情况下解决这个问题的最简单方法是什么(服务器管理员认为更新的版本“不稳定”?

    一种解决方案是,我可以让xpath返回第一个$result中的字段,这样就不必迭代 $block[0]->Fields->Field

    2 回复  |  直到 15 年前
        1
  •  4
  •   Josh Davis    15 年前

    正如斯约德在回答中提到的, $block 不是数组。 SimpleXMLElement::xpath() 返回一个对象数组,每个对象表示一个元素。所以基本上,你必须 $block[0] 具有 $块 因为它已经代表了你要找的街区。

    另外,我还重写了XPath表达式。既然你在找一个 <data:Block/> 元素,这是你应该瞄准的。关于 <data:Code/>

    foreach ($xml->xpath('//data:Block[data:Code="Fbf"]') as $block) {
        foreach ($block->Fields->Field as $field) {
            echo "Code: ". $field->Code ."\n"; // SHould return FinnsIFbf
        }
    }
    

    更新

    我没注意到你说你只对 <Field/> 元素。在这种情况下,您可以直接通过XPath获得它:(记住它们都在数据名称空间中)

    foreach ($xml->xpath('//data:Block[data:Code="Fbf"]/data:Fields/data:Field') as $field) {
        echo "Code: ". $field->Code ."\n"; // SHould return FinnsIFbf
    }
    
        2
  •  0
  •   Sjoerd    15 年前

    可能是因为$block不是数组。你应该使用 var_dump print_r 确认一下,然后用 is_array 以确保它是一个数组。

    如果SimpleXML找到多个同名元素,它将返回一个对象数组。如果它找到一个元素,则只返回该元素,而不是返回一个包含单个元素的数组。因此,当您需要多个元素时,总是必须为只有一个元素的情况编写一个异常情况代码。