用于 PHP DOMDocument 的类 jQuery 选择器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1124271/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery-like selectors for PHP DOMDocument
提问by Strae
I'm working with a DOMDocument, and I'm wondering if there exists some way of using CSS-like selectors to select nodes like we would in jQuery.
我正在使用DOMDocument,我想知道是否存在某种使用类似 CSS 的选择器来选择节点的方法,就像我们在jQuery 中所做的那样。
Example situation: I'm parsing an XML file, one snippet of which looks like this:
示例情况:我正在解析一个 XML 文件,其中一个片段如下所示:
<gesmes:Envelope>
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time="2009-07-13">
<Cube currency="USD" rate="1.3975"/>
<Cube currency="JPY" rate="129.03"/>
<Cube currency="BGN" rate="1.9558"/>
<Cube currency="CZK" rate="26.028"/>
</Cube>
</Cube>
</gesmes:Envelope>
Accessing this structure with jQuery-like selectors would be dead simple. For example, I could use
使用类似 jQuery 的选择器访问此结构将非常简单。例如,我可以使用
$("Cube[currency]")
to retrieve all the Cubeelements with the 'currency' attribute.
检索Cube具有“货币”属性的所有元素。
But how can I do the same thing with PHP's DOMDocument? I'd like to select elements which have an attribute, or have a particular attribute value.
但是我怎么能用 PHP 做同样的事情DOMDocument呢?我想选择具有属性或具有特定属性值的元素。
回答by Christophe Eblé
If you want to manipulate the DOM ala Jquery, PHPQuery is something for you.
如果您想操作 DOM ala Jquery,PHPQuery 非常适合您。
http://code.google.com/p/phpquery/
http://code.google.com/p/phpquery/
A simple example of what you can do with it.
一个简单的例子,说明你可以用它做什么。
// almost everything can be a chain
$li = null;
$doc['ul > li']
->addClass('my-new-class')
->filter(':last')
->addClass('last-li');
回答by AnalyticaL
Take a look at the DOMXPathclass in PHP. It uses XPath, so you'll need to read up on XPath syntax if you're unfamiliar with it. There's some documentation on MSDNor W3Schools, or you can read the W3 specif you're particularly brave.
看一看DOMXPathPHP中的类。它使用 XPath,因此如果您不熟悉 XPath 语法,则需要阅读它。在MSDN或W3Schools上有一些文档,或者如果您特别勇敢,可以阅读W3 规范。
To solve your example problem: //cube[@currency]is an XPath query that selects all elements in the document with a currency attribute. Usage of this with the DOMXPathclass would look like this:
解决您的示例问题://cube[@currency]是一个 XPath 查询,它选择文档中具有货币属性的所有元素。在DOMXPath类中使用 this看起来像这样:
$xpath = new DOMXpath($myDomDocument);
$cubesWithCurrencies = $xpath->query('//cube[@currency]');
$cubesWithCurrenciesis now a DOMNodeListthat you can iterate over.
$cubesWithCurrencies现在是一个DOMNodeList你可以迭代的。
回答by John Slegers
I created a library that allows you to crawl HTML5 and XML documents just like you do with jQuery.
我创建了一个库,允许您像使用 jQuery 一样抓取 HTML5 和 XML 文档。
You can find the library on GitHub.
您可以在 GitHub 上找到该库。
It should allow you to do exactly what you want!
它应该让你做你想做的事!
Under the hood, it uses symfony/DomCrawlerfor conversion of CSS selectors to XPath selectors. It always uses the same DomDocument, even when passing one object to another, to ensure decent performance.
在幕后,它使用symfony/DomCrawler将 CSS 选择器转换为 XPath 选择器。它始终使用相同的 DomDocument,即使将一个对象传递给另一个对象,以确保良好的性能。
The library also includes its own zero config autoloader for PSR-0 compatible libraries. The example included should work out of the box without any additional configuration.
该库还包括其自己的用于 PSR-0 兼容库的零配置自动加载器。包含的示例应该是开箱即用的,无需任何额外配置。
Example use:
使用示例:
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('<div class="site-center"></div>');
// 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('<section><div class="footer-wrapper"></div></section>');
[...]
支持的方法:
- [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
- [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
- Renamed 'select', for obvious reasons
- Renamed 'void', since 'empty' is a reserved word in PHP
- 重命名“选择”,原因显而易见
- 重命名为 'void',因为 'empty' 是 PHP 中的保留字
回答by zioMitch
You can use the Symfony DomCrawler component, enabling you to use css selectors for DOM traversing: https://packagist.org/packages/symfony/dom-crawler
您可以使用 Symfony DomCrawler 组件,使您能够使用 css 选择器进行 DOM 遍历:https://packagist.org/packages/symfony/dom-crawler
回答by usoban
XPath is exactly what you are looking for, here is pretty good list of possible selectors
XPath 正是您要寻找的,这里是可能的选择器的不错列表

