【问题标题】:PHP: Check if XML node exists with attributePHP:检查XML节点是否存在属性
【发布时间】:2023-04-03 08:09:01
【问题描述】:

我似乎无法弄清楚这一点。我有以下 XML 文件:

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

我需要能够测试是否存在具有给定名称的&lt;building&gt; 节点。我似乎在 Google 上找到的所有内容都告诉我执行以下操作:

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

...但是如果我理解正确,那不是只测试第一个&lt;building&gt; 节点吗? item(0)?我需要为此使用 XQuery 吗?

我会很感激一些帮助!谢谢!

【问题讨论】:

    标签: php xml xpath


    【解决方案1】:

    我建议如下(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);
    }
    

    【讨论】:

    • 看起来上面的 xpath 函数缺少右括号 ")" 。否则,感谢伟大的代码
    【解决方案2】:

    好的,看起来 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;
    }
    
    ?>
    

    【讨论】:

      【解决方案3】:

      这个 XPath 表达式

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

      选择名为building 的元素,其name 属性的值为'Shiny Red',并且是顶部元素的子元素的子元素。

      可能在 PHP 中有一种评估 XPath 表达式的方法,然后只需评估上面的 XPath 表达式并使用结果

      【讨论】:

        【解决方案4】:

        如果我理解正确,那不是只测试第一个节点吗?

        是的。因此,如果您想使用类似的 DOM 方法,则必须循环执行。例如:

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

        使用 XPath,您可以消除循环,正如 Dimitre 和 sgehrig 所发布的那样,但您必须小心允许将哪些字符注入 XPath 表达式(例如,$name= '"]' 会中断表达式)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-04-08
          • 2021-06-06
          • 2019-04-11
          • 1970-01-01
          • 2020-06-09
          • 2016-08-29
          • 1970-01-01
          相关资源
          最近更新 更多