php - 如何从 DOM 中删除无效元素?

标签 php javascript html dom xpath

我们有以下代码列出了找到 $value 的 xpath。

我们检测到给定的 URL(见图片)有一个非标准标签 td1,它也没有结束标签。正如您在下面的屏幕截图中所见,可能是网站开发人员有意将其放在那里。

此元素会在识别节点的正确 XPath 时产生问题。

一个损坏的 Xpath 示例:

/html/body/div[2]/div[2]/table/tr[2]/td/table/tr[1]/td[2]/table/tr[2]/td[2]/table[3]/tr[2]/**td1**/td[2]/span/u[1]

(如您所见,td1 在 Xpath 中被识别和链接)

我们认为通过删除此元素可以帮助我们构建我们所追求的有效 XPath。

一个有效的例子是

/html/body/div[2]/div[2]/table/tr[2]/td/table/tr[1]/td[2]/table/tr[2]/td[2]/table[3]/tr[2]/td[2]/span/u[1]

我们如何移除 DOMXpath 中的先前加载?您还有其他方法吗?

我们想删除所有可能不是 td1 的无效标签,如 h8、diw 等...

private function extract($url, $value) {

        $dom = new DOMDocument();

        $file = 'content.txt';
        //$current = file_get_contents($url);
        $current = CurlTool::downloadFile($url, $file);
        //file_put_contents($file, $current);

        @$dom->loadHTMLFile($current);

        //use DOMXpath to navigate the html with the DOM
        $dom_xpath = new DOMXpath($dom);

        $elements = $dom_xpath->query("//*[text()[contains(., '" . $value . "')]]");
        var_dump($elements);
        if (!is_null($elements)) {

            foreach ($elements as $element) {
                var_dump($element);
                echo "\n1.[" . $element->nodeName . "]\n";

                $nodes = $element->childNodes;
                foreach ($nodes as $node) {
                    if( ($node->nodeValue != null) && ($node->nodeValue === $value) ) {
                        echo '2.' . $node->nodeValue . "\n";
                        $xpath = preg_replace("/\/text\(\)/", "", $node->getNodePath());
                        echo '3.' . $xpath . "\n";
                    }
                }
            }
        }
    }

enter image description here

最佳答案

您可以使用 XPath 找到有问题的节点并删除它们,同时将其子节点提升到 DOM 中的位置。那么您的路径将是正确的。

$dom_xpath = new DOMXpath($dom);
$results = $dom_xpath->query('//td1'); // (or any offending element)
foreach ($results as $invalidNode)
{
    $parentNode = $invalidNode->parentNode;
    while ($invalidNode->childNodes)
    {
        $firstChild = $invalidNode->firstChild;
        $parentNode->insertBefore($firstChild,$invalidNode);
    }
    $parentNode->removeChild($invalidNode);
}

编辑:

您还可以通过使用有效元素列表并否定它来构建违规元素列表。

// Build list manually from the HTML spec:
// See: http://www.w3.org/TR/html5/section-index.html#elements-1
$validTags = array();

// Convert list to XPath:
$validTagsStr = '';
foreach ($validTags as $tag)
{
    if ($validTagsStr)
    {   $validTagsStr .= ' or ';    }
    $validTagsStr .= 'self::'.$tag;
}
$results = $dom_xpath->query('//*[not('.$validTagsStr.')');

关于php - 如何从 DOM 中删除无效元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12803321/

相关文章:

html - 如何在悬停时更改文本框内容

html - 为什么我的导航栏不会在页面中心下拉菜单?

php - __soapCall 什么都不返回

php - 分析建议 - 试图查明网站加载问题

JavaScript 键盘,Shift + 组合键

html - 为什么样式看起来像按钮的链接延伸得非常宽?

php - 如何限制学说 2 中结果集的大小?

php - 使用PHP上传gif图片到服务器不丢失动画

javascript - 在加载所有 Meteor 模板加载结束时运行 Javascript

javascript - 动画时换行的子元素