我正在使用PHP DOM,并试图在具有给定类名的DOM节点中获取一个元素。获取该子元素的最佳方法是什么?
PHP:我最终使用的是Mechanize
,它更容易使用。
发布于 2011-06-16 10:07:34
css更新: Xpath版本的 *[@class~='my-class']
选择器
因此,在我对hakre的评论进行了下面的评论之后,我变得很好奇,并研究了Zend_Dom_Query
背后的代码。上面的选择器看起来被编译成了下面的xpath (未经测试):
[contains(concat(' ', normalize-space(@class), ' '), ' my-class ')]
所以PHP应该是:
$dom = new DomDocument();
$dom->load($filePath);
$finder = new DomXPath($dom);
$classname="my-class";
$nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");
基本上,我们在这里所做的就是规范化class
属性,这样即使是单个类也是以空格为边界的,而完整的类列表也是以空格为边界的。然后在我们要搜索的类后面加上一个空格。通过这种方式,我们可以有效地查找并找到my-class
的实例。
使用xpath选择器?
$dom = new DomDocument();
$dom->load($filePath);
$finder = new DomXPath($dom);
$classname="my-class";
$nodes = $finder->query("//*[contains(@class, '$classname')]");
如果只有一种类型的元素,您可以用特定的标记名替换*
。
如果你需要用非常复杂的选择器做很多这样的事情,我推荐Zend_Dom_Query
,它支持CSS选择器语法(就像jQuery一样):
$finder = new Zend_Dom_Query($html);
$classname = 'my-class';
$nodes = $finder->query("*[class~=\"$classname\"]");
发布于 2012-11-01 22:47:01
如果您希望获得不带zend的类的innerhtml,您可以使用以下命令:
$dom = new DomDocument();
$dom->load($filePath);
$classname = 'main-article';
$finder = new DomXPath($dom);
$nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");
$tmp_dom = new DOMDocument();
foreach ($nodes as $node)
{
$tmp_dom->appendChild($tmp_dom->importNode($node,true));
}
$innerHTML.=trim($tmp_dom->saveHTML());
echo $innerHTML;
发布于 2014-11-03 12:53:10
我认为公认的方法更好,但我想这也可能行得通
function getElementByClass(&$parentNode, $tagName, $className, $offset = 0) {
$response = false;
$childNodeList = $parentNode->getElementsByTagName($tagName);
$tagCount = 0;
for ($i = 0; $i < $childNodeList->length; $i++) {
$temp = $childNodeList->item($i);
if (stripos($temp->getAttribute('class'), $className) !== false) {
if ($tagCount == $offset) {
$response = $temp;
break;
}
$tagCount++;
}
}
return $response;
}
https://stackoverflow.com/questions/6366351
复制相似问题