I’m using SimpleXMLElement to read xml returned from a remote server.
The results are then parsed with xpath like this:
$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
}
}
The $result is an Array with SimpleXMLElement objects. The actual error occurs when trying to use $block[0]->Fields(SimpleXMLElement object) as an array. So the results are there. It’s iterating that is the problem.
This works just fine in PHP 5.3.2, but on the server which is running 5.1.6 it fails with:
Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference
What’s the simplest way to fix this without upgrading the server version (server admin thinks its “unstable” with a newer version)?
One solution could be if I could make the xpath return the Field in the first $result, so I wont have to iterate the $block[0]->Fields->Field but I failed to make such an xpath expression.
As was mentionned in Sjoerd’s answer,
$blockis not an array. SimpleXMLElement::xpath() returns an array of objects, each of those objects representing one single element. So basically, you have to replace$block[0]with$blocksince it already represents the block you’re looking for.Also, I have rewritten your XPath expression. Since you’re looking for a
<data:Block/>element, that’s what you should target. The thing about<data:Code/>is a predicate, so it should go within brackets. Of course in your case the result is the same, but it’s good practice to have semantically correct expressions, helps having a clearer idea of what’s going on later on when you re-read that code (or if someone else has to maintain it.)Update
I didn’t notice that you said that all you were interested in was the
<Field/>element. In that case you can get it directly through XPath: (remember that they’re all in the data namespace)