Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: Check if XML node exists with attribute

Tags:

php

xml

xpath

I can't seem to figure this one out. I have the following XML file:

<?xml version="1.0" encoding="UTF-8"?>
<targets>
  <showcases>
    <building name="Big Blue" />
    <building name="Shiny Red" />
    <building name="Mellow Yellow" />
  </showcases>
</targets>

I need to be able to test whether or not a <building> node exists with a given name. Everything I seem to find on Google tells me to do something like the following:

$xdoc->getElementsByTagName('building')->item(0)->getAttributeNode('name')

... but if I understand that correctly, doesn't that only test the first <building> node? item(0)? Do I need to use XQuery for this?

I'd appreciate some help! Thanks!

like image 361
neezer Avatar asked Mar 31 '09 02:03

neezer


2 Answers

I'd suggest the following (PHP using ext/simplexml and XPath):

$name = 'Shiny Red';
$xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8"?>
<targets>
  <showcases>
    <building name="Big Blue" />
    <building name="Shiny Red" />
    <building name="Mellow Yellow" />
  </showcases>
</targets>');
$nodes = $xml->xpath(sprintf('/targets/showcases/building[@name="%s"]', $name);
if (!empty($nodes)) {
    printf('At least one building named "%s" found', $name);
} else {
    printf('No building named "%s" found', $name);
}
like image 188
Stefan Gehrig Avatar answered Nov 18 '22 12:11

Stefan Gehrig


Okay, looks like XPath was what I wanted. Here's what I came up with that does what I want:

<?php

$xmlDocument = new DOMDocument();

$nameToFind = "Shiny Red";

if ($xmlDocument->load('file.xml')) {
        if (checkIfBuildingExists($xmlDocument, $nameToFind)) {
        echo "Found a red building!";
    }
}

function checkIfBuildingExists($xdoc, $name) {
    $result = false;
    $xpath = new DOMXPath($xdoc);
    $nodeList = $xpath->query('/targets/showcases/building', $xdoc);
    foreach ($nodeList as $node) {
        if ($node->getAttribute('name') == $name) {
            $result = true;
        }
    }
    return $result;
}

?>
like image 3
neezer Avatar answered Nov 18 '22 10:11

neezer