I have an XML file that I'm reading as a SimpleXML Element. In that file I have the following elements:
<files>
<file>
<type>GIF</type>
<url>http://dl.server.com/1.GIF</url>
</file>
<file>
<type>JPG</type>
<url>http://dl.server.com/2.JPG</url>
</file>
<file>
<type>TIF</type>
<url>http://dl.server.com/1.TIF</url>
</file>
<file>
<type>EPS</type>
<url>http://dl.server.com/1.EPS</url>
</file>
<file>
<type>LEPS</type>
<url>http://dl.server.com/2.EPS</url>
</file>
</files>
I was using a foreach() to loop through and based on the element's value, was performing an action. Now I need to look at all the files->file->type values and if "LEPS" exists, use that URL, otherwise if "EPS" exists, use that URL, and if neither exists, do nothing.
My struggle is with the XML node/element/property terms and not being able to find a way to query if files->file->type = "LEPS" is true or not. While I know how to check for attributes (isset(element['attributename']), I'm not sure how to check for an element with a specific property value.
Sorry for the elementary question!
You can use a predicate to check the <type>
and those of the sibling file/types.
//files/file
[
type='LEPS' or
type='EPS' and not(
following-sibling::file/type='LEPS' or
preceding-sibling::file/type='LEPS'
)
]/url
(This example uses the DOM extension rather than SimpleXML for reasons of taste. The xpath expression itself is agnostic and can be applied equally in either.)
/* $xml = your xml string */
$dom = new DOMDocument();
$dom->loadXML($xml);
$xpath = new DOMXPath($dom);
$query = <<<'XPATH'
//files/file
[
type='LEPS' or
type='EPS' and not(
following-sibling::file/type='LEPS' or
preceding-sibling::file/type='LEPS'
)
]/url
XPATH;
foreach ($xpath->query($query) as $node) {
echo $dom->saveXML($node), "\n";
}
<url>http://dl.server.com/2.EPS</url>