用于PHP DOMDocument的类jQuery选择器

我正在使用DOMDocument ,我想知道是否存在一些使用类似CSS的选择器来选择节点的方法,就像我们在jQuery中一样 。

示例情况:我正在解析XML文件,其中一个片段如下所示:

  Reference rates  European Central Bank           

使用类似jQuery的选择器访问此结构将非常简单。 例如,我可以使用

 $("Cube[currency]") 

使用’currency’属性检索所有Cube元素。

但是我怎么能用PHP的DOMDocument做同样的事情呢? 我想选择具有属性或具有特定属性值的元素。

如果你想操纵DOM ala Jquery,PHPQuery是适合你的。

http://code.google.com/p/phpquery/

一个简单的例子,你可以用它做什么。

 // almost everything can be a chain $li = null; $doc['ul > li'] ->addClass('my-new-class') ->filter(':last') ->addClass('last-li'); 

看一下PHP中的DOMXPath类。 它使用XPath,因此如果您不熟悉它,则需要阅读XPath语法。 有关MSDN或W3Schools的一些文档,或者如果你特别勇敢,你可以阅读W3规范 。

要解决您的示例问题: //cube[@currency]是一个XPath查询,它使用currency属性选择文档中的所有元素。 使用DOMXPath类的方法如下所示:

 $xpath = new DOMXpath($myDomDocument); $cubesWithCurrencies = $xpath->query('//cube[@currency]'); 

$cubesWithCurrencies现在是一个可以迭代的DOMNodeList

我创建了一个库,允许您像使用jQuery一样抓取HTML5和XML文档。

您可以在GitHub上找到该库。

它应该让你做你想要的!

在引擎盖下,它使用symfony / DomCrawler将CSS选择器转换为XPath选择器。 即使将一个对象传递给另一个对象,它也始终使用相同的DomDocument,以确保良好的性能。

该库还包含自己的零配置自动加载器,用于PSR-0兼容库。 包含的示例应该开箱即用,无需任何其他配置。


使用示例:

 namespace PowerTools; // Get file content $htmlcode = file_get_contents( 'https://github.com' ); // Define your DOMCrawler based on file string $H = new DOM_Query( $htmlcode ); // Define your DOMCrawler based on an existing DOM_Query instance $H = new DOM_Query( $H->select('body') ); // Passing a string (CSS selector) $s = $H->select( 'div.foo' ); // Passing an element object (DOM Element) $s = $H->select( $documentBody ); // Passing a DOM Query object $s = $H->select( $H->select('p + p') ); // Select the body tag $body = $H->select('body'); // Combine different classes as one selector to get all site blocks $siteblocks = $body->select('.site-header, .masthead, .site-body, .site-footer'); // Nest your methods just like you would with jQuery $siteblocks->select('button')->add('span')->addClass('icon icon-printer'); // Use a lambda function to set the text of all site blocks $siteblocks->text(function( $i, $val) { return $i . " - " . $val->attr('class'); }); // Append the following HTML to all site blocks $siteblocks->append('
'); // Use a descendant selector to select the site's footer $sitefooter = $body->select('.site-footer > .site-center'); // Set some attributes for the site's footer $sitefooter->attr(array('id' => 'aweeesome', 'data-val' => 'see')); // Use a lambda function to set the attributes of all site blocks $siteblocks->attr('data-val', function( $i, $val) { return $i . " - " . $val->attr('class') . " - photo by Kelly Clark"; }); // Select the parent of the site's footer $sitefooterparent = $sitefooter->parent(); // Remove the class of all i-tags within the site's footer's parent $sitefooterparent->select('i')->removeAttr('class'); // Wrap the site's footer within two nex selectors $sitefooter->wrap('
'); [...]

支持的方法:

  • [x] $ (1)
  • [x] $ .parseHTML
  • [x] $ .parseXML
  • [x] $ .parseJSON
  • [x] $ selection.add
  • [x] $ selection.addClass
  • [x] $ selection.after
  • [x] $ selection.append
  • [x] $ selection.attr
  • [x] $ selection.before
  • [x] $ selection.children
  • [x] $ selection.closest
  • [x] $ selection.contents
  • [x] $ selection.detach
  • [x] $ selection.each
  • [x] $ selection.eq
  • [x] $ selection.empty (2)
  • [x] $ selection.find
  • [x] $ selection.first
  • [x] $ selection.get
  • [x] $ selection.insertAfter
  • [x] $ selection.insertBefore
  • [x] $ selection.last
  • [x] $ selection.parent
  • [x] $ selection.parents
  • [x] $ selection.remove
  • [x] $ selection.removeAttr
  • [x] $ selection.removeClass
  • [x] $ selection.text
  • [x] $ selection.wrap

  1. 出于显而易见的原因,重命名为“选择”
  2. 重命名为’void’,因为’empty’是PHP中的保留字

您可以使用Symfony DomCrawler组件,使您可以使用css选择器进行DOM遍历: https ://packagist.org/packages/symfony/dom-crawler

XPath正是您正在寻找的, 这里有很好的选择器列表