XPath 查找具有空值的属性

问题描述

我使用 DOMDocument 加载 html,然后对其应用 DOMXPath 过滤器。这些对象中是否有任何一种方法可以区分具有空字符串值的属性和没有值的属性

<input required="">
<input required>

我知道在这两种情况下,required 属性在技术上都是正确的,但是当我调用 DOMDocument::saveHTML() 时,我可以看到它们如图所示。现在我只想过滤那些具有空字符串值的内容。我找到的最接近的解决方案是

$xpath = new DOMXPath($dom);
$xpath->query("//*[@*[string-length()=0]]");

但不幸的是,这也匹配了没有值的属性

解决方法

正如我在评论中提到的,DOMDocument 将尝试从 HTML 生成有效的 XML 文档。据我所知,它不能正确支持没有值的 HTML5 样式属性。所以我不确定 XPath 是否适用于这种情况。

但是在对文档底层的实际 DOM 进行了一些实验之后,似乎虽然元素有一个属性节点,但没有值的文本节点。

因此以下检查这种情况...

$a = '<input required="">
<input required>'
;

$dom = new DOMDocument();
$dom->loadHTML($a,LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);

foreach ( $xpath->query("//*[@*[string-length()=0]]") as $tag)  {
    if ( isset($tag->attributes[0]->firstChild) ){
        echo "with attribute value:" . $dom->saveHTML($tag) . PHP_EOL;
    }
    else    {
        echo "without attribute value:" . $dom->saveHTML($tag) . PHP_EOL;
    }
}

显示....

with attribute value:<input required="">
without attribute value:<input required>

刚刚注意到代码使用了 attributes[0],因为它纯粹是为了测试目的。您需要根据需要更改此设置。