我不知道如何解决这个问题
<div>
<p id="p1"> Price is <span>$ 25</span></p>
<p id='p2'> But this price is $ <span id="s1">50,23</span> </p>
<p id='p3'> This one : $ 14540.12 dollar</p>
</div>
我正在尝试做的是找到一个带有价格的元素,这是达到它的最短路径。
这就是我的沙发。
$elements = $dom->getElementsByTagName('*');
foreach($elements as $child)
{
if (preg_match("/.$regex./",$child->nodeValue)){
echo $child->getNodePath(). "<br />";
}
}
这导致
/html
/html/body
/html/body/div
/html/body/div/p[1]
/html/body/div/p[1]/span
/html/body/div/p[2]
/html/body/div/p[2]/span
/html/body/div/p[3]
这些是我想要的元素的路径,因此在此测试HTML中可以。但是在真实的网页中,这些路径很长而且容易出错。
我想做的是找到具有ID属性的最接近的元素,并进行引用。
因此,一旦找到与$ regex相匹配的元素,我就需要向上移动DOM并找到具有ID属性的第一个元素,并从中创建新的较短路径。
在上面的HTML示例中,有3个与$ regex匹配的价格。价格在:
//p[@id="p1"]/span
//p[@id="s1"]
//p[@id="p3"]
这就是我想从函数中返回的内容。这意味着我还需要摆脱存在的所有其他路径,因为它们不包含$ regex
有什么帮助吗?
最佳答案
您可以使用XPath跟随祖先路径到达包含@id
属性的第一个节点,然后切断其路径。没有清理代码,但是像这样:
// snip
$xpath = new DomXPath($doc);
foreach($elements as $child)
{
$textValue = '';
foreach ($xpath->query('text()', $child) as $text)
$textValue .= $text->nodeValue;
if (preg_match("/.$regex./", $textValue)) {
$path = $child->getNodePath();
$id = $xpath->query('ancestor-or-self::*[@id][1]', $child)->item(0);
$idpath = '';
if ($id) {
$idpath = $id->getNodePath();
$path = '//'.$id->nodeName.'[@id="'.$id->attributes->getNamedItem('id')->value.'"]'.substr($path, strlen($idpath));
}
echo $path."\n";
}
}
打印类似
/html
/html/body
/html/body/div
//p[@id="p1"]
//p[@id="p1"]/span
//p[@id="p2"]
//span[@id="s1"]
//p[@id="p3"]
关于php - 遍历DOM向后查找ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20662930/