Reputation: 4046
In all the examples of simplexml I have seen the structure of the xml is like:
<examples>
<example>
</example>
<example>
</example>
<example>
</example>
</examples>
However I am dealing with xml in the form:
<examples>
<example>
</example>
<example>
</example>
<example>
</example>
</examples>
<app>
<appdata>
<error>
<Details>
<ErrorCode>101</ErrorCode>
<ErrorDescription>Invalid Username and Password</ErrorDescription>
<ErrorSeverity>3</ErrorSeverity>
<ErrorSource />
<ErrorDetails />
</Details>
</error>
<items>
<item>
</item>
<item>
</item>
</items>
</appdata>
</app>
I would like to skip the examples stuff, and go straight to the app tag and check if the error errorcode exists and if it doesn't, go to the items array and loop through it.
My current way of handling this is:
$items = new SimpleXMLElement($xml_response);
foreach($items as $item){
//in here I check the presence of the object properties
}
Is there a better way? The problem is the xml structure sometimes changes order so I want to be able to go straight to particular parts of the xml.
Upvotes: 2
Views: 862
Reputation: 9520
This kind of thing is very easy using XPath, and handily, SimpleXML has an xpath
function built into it! XPaths allow you to select nodes in a graph based on their ancestors, descendants, attributes, values, and so on.
Here is an example of using SimpleXML's xpath
function to extract data from your XML. Note that I added an extra parent element to the sample you posted so that the XML would validate.
$sxo = new SimpleXMLElement($xml);
# this selects all 'error' elements with parent 'appdata', which has parent 'app'
$error = $sxo->xpath('//app/appdata/error');
if ($error) {
# go through the error elements...
while(list( , $node) = each($error)) {
# get the error details
echo "Found an error!" . PHP_EOL;
echo $node->Details->ErrorCode
. ", severity " . $node->Details->ErrorSeverity
. ": " . $node->Details->ErrorDescription . PHP_EOL;
}
}
Output:
Found an error!
101, severity 3: Invalid Username and Password
Here's another example -- I edited the XML excerpt slightly to show the results better here:
// edited <items> section of the XML you posted:
<items>
<item>Item One
</item>
<item>Item Two
</item>
</items>
# this selects all 'item' elements under appdata/items:
$items = $sxo->xpath('//appdata/items/item');
foreach ($items as $i) {
echo "Found item; value: " . $i . PHP_EOL;
}
Output:
Found item; value: Item One
Found item; value: Item Two
There's more information in the SimpleXML XPath documentation, and try the zvon.org XPath tutorials -- they give a good grounding in XPath 1.0 syntax.
Upvotes: 1