PHP: проверьте, существует ли узел XML с атрибутом - PullRequest
7 голосов
/ 31 марта 2009

Я не могу понять это. У меня есть следующий XML-файл:

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

Мне нужно проверить, существует ли узел <code><building> с заданным именем. Все, что я нахожу в Google, говорит мне сделать что-то вроде следующего:

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

... но если я правильно понимаю, разве это не проверяет только первый <building> узел? item(0)? Нужно ли для этого использовать XQuery?

Буду признателен за помощь! Спасибо!

Ответы [ 4 ]

9 голосов
/ 31 марта 2009

Я бы предложил следующее (PHP использует ext / simplexml и 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);
}
3 голосов
/ 31 марта 2009

Хорошо, похоже, что XPath был тем, что я хотел. Вот что я придумал, что делает то, что я хочу:

<?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;
}

?>
1 голос
/ 31 марта 2009

если я правильно понимаю, разве это не проверяет только первый узел?

Да. Поэтому, если вы хотите использовать такие методы DOM, вам придется делать это в цикле. eg.:

$buildings= $xdoc->getElementsByTagName('building');
foreach ($buildings as $building)
    if ($building->getAttribute('name')==$name)
        return true;
return false;

С помощью XPath вы можете устранить цикл, как было опубликовано Dimitre и sgehrig, но вам нужно быть осторожным с тем, какие символы вы можете вставить в выражение XPath (например, $ name = '"]' прервется выражение).

1 голос
/ 31 марта 2009

Это выражение XPath :

/*/*/building[@name = 'Shiny Red']

выбирает элемент с именем building, значением атрибута которого name является 'Shiny Red', который является дочерним элементом дочернего элемента верхнего элемента.

Возможно, в PHP есть способ оценить выражения XPath, а затем просто оценить приведенное выше выражение XPath и использовать результат .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...