Php 向后遍历DOM查找id
我不知道怎么解决这个问题Php 向后遍历DOM查找id,php,dom,xpath,Php,Dom,Xpath,我不知道怎么解决这个问题 <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>
<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>
这些是我想要的元素的路径,所以在这个测试HTML中没有问题。但在真实的网页中,这些路径很长,并且容易出错。
我想做的是找到具有ID属性的最近元素并引用它
因此,一旦找到与$regex匹配的and元素,我需要遍历DOM,找到具有and 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/正文
/html/body/div
//p[@id=“p1”]
//p[@id=“p1”]/span
//p[@id=“p2”]
//span[@id=“s1”]
//p[@id=“p3”]
我应该改用SimpleXML吗?因此,这将是某种预处理分析,以准备将要应用的实际XSLT?有趣!伟大的詹斯!这是有效的,它确实给了我如上所述的输出。现在我想删除不必要的路径。在本例中,我只需要//p[@id=“p1”]/span、//span[@id=“s1”]和//p[@id=“p3”]。我怎样才能做到这一点?什么是“不必要的路径”?无论如何,这可能更适合作为一个新问题。不要把这当作一个新问题。我正在寻找包含$regex的元素的最短路径。正如您在上面的答案中所看到的,这些路径是//p[@id=“p1”]/span//span[@id=“s1”]//p[@id=“p3”]所以我不需要/html、/html/body等。也不需要//p[@id=“p1”]因为正则表达式是在下面的span中找到的(参见上面的输出),所以在我的示例中,我只需要3行输出,剩下的是不必要的,我仍然不知道如何过滤路径,我不认为你在你的问题中描述了这一点。如果我遗漏了什么,请强调我遗漏了什么。我没有用你的正则表达式改变任何东西,那一定是从一开始就被破坏了。Jens谢谢,我已经重写了我的问题,我希望这能让事情变得更清楚。感谢你的帮助!
/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]
// 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";
}
}