PHP:检查是否存在带有属性的 XML 节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/699821/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP: Check if XML node exists with attribute
提问by neezer
I can't seem to figure this one out. I have the following XML file:
我似乎无法弄清楚这一点。我有以下 XML 文件:
<?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 node exists with a given name. Everything I seem to find on Google tells me to do something like the following:<building>
我需要能够测试是否存在具有给定名称的节点。我似乎在 Google 上找到的所有内容都告诉我执行以下操作:<building>
$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?
...但如果我理解正确,那不是只测试第一个<building>节点吗? item(0)? 我需要为此使用 XQuery 吗?
I'd appreciate some help! Thanks!
我很感激一些帮助!谢谢!
回答by Stefan Gehrig
I'd suggest the following (PHP using ext/simplexml and XPath):
我建议如下(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);
}
回答by neezer
Okay, looks like XPath was what I wanted. Here's what I came up with that does what I want:
好的,看起来 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;
}
?>
回答by Dimitre Novatchev
This XPath expression:
这个 XPath 表达式:
/*/*/building[@name = 'Shiny Red']
/*/*/building[@name = 'Shiny Red']
selects the element named buildingthe value of whose nameattribute is 'Shiny Red' and that is a child of a child of the top element.
选择名为“Shiny Red”属性building值的name元素,该元素是顶部元素的子元素的子元素。
Probably in PHP there is a way to evaluate XPath expressions, then just evaluate the above XPath expression and use the result.
可能在 PHP 中有一种方法可以评估 XPath 表达式,然后只需评估上面的 XPath 表达式并使用结果。
回答by bobince
if I understand that correctly, doesn't that only test the first node?
如果我理解正确,那不是只测试第一个节点吗?
Yes. So if you want to use DOM methods like that one, you'll have to do it in a loop. eg.:
是的。因此,如果您想使用这样的 DOM 方法,则必须在循环中进行。例如。:
$buildings= $xdoc->getElementsByTagName('building');
foreach ($buildings as $building)
if ($building->getAttribute('name')==$name)
return true;
return false;
With XPath you can eliminate the loop, as posted by Dimitre and sgehrig, but you'd have to be careful about what characters you allow to be injected into the XPath expression (eg. $name= '"]' will break the expression).
使用 XPath,您可以消除循环,正如 Dimitre 和 sgehrig 所发布的那样,但是您必须小心允许将哪些字符注入到 XPath 表达式中(例如,$name= '"]' 会破坏表达式) .

