我似乎无法想出这个。我有以下XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<targets>
<showcases>
<building name="Big Blue" />
<building name="Shiny Red" />
<building name="Mellow Yellow" />
</showcases>
</targets>
我需要能够测试具有给定名称的
节点是否存在。我在Google上看到的所有内容都告诉我要执行以下操作:<building>
<building>
...但如果我理解正确,那不是只测试第一个$xdoc->getElementsByTagName('building')->item(0)->getAttributeNode('name')
节点吗? <building>
?我需要使用XQuery吗?
我很感激一些帮助!谢谢!
答案 0 :(得分:9)
我建议如下(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);
}
答案 1 :(得分:3)
好的,看起来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;
}
?>
答案 2 :(得分:1)
此XPath表达式:
<强> /*/*/building[@name = 'Shiny Red']
强>
选择名为building
的元素,其name
属性的值为'Shiny Red',并且该元素是top元素的子元素。
可能在PHP中有一种评估XPath表达式的方法,然后只评估上面的XPath表达式并使用结果。
答案 3 :(得分:1)
如果我理解正确,那不是只测试第一个节点吗?
是。因此,如果你想使用像那样的DOM方法,你必须在循环中完成它。例如:
$buildings= $xdoc->getElementsByTagName('building');
foreach ($buildings as $building)
if ($building->getAttribute('name')==$name)
return true;
return false;
使用XPath你可以消除循环,就像Dimitre和sgehrig发布的那样,但是你必须要小心你允许将哪些字符注入到XPath表达式中(例如。$ name ='“]'会破坏表达)。