-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[DomCrawler] Add support for XPath expression evaluation #19430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
$prefixes = $this->findNamespacePrefixes($xpath); | ||
|
||
foreach ($this->nodes as $node) { | ||
$domxpath = $this->createDOMXPath($node->ownerDocument, $prefixes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use a single DOMXPath now. As of Symfony 3, it is impossible to have nodes belonging to different documents. They will all belong to $this->document
(which can only be null
for an empty root crawler, i.e. a crawler not yet initialized)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! PR updated.
a6a5cfe
to
e288fd3
Compare
{ | ||
$data = array(); | ||
$prefixes = $this->findNamespacePrefixes($xpath); | ||
$domxpath = $this->createDOMXPath($this->document, $prefixes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would throw a LogicException before that in case $this->document
is null, saying you cannot evaluate an expression on an uninitialized crawler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 done
e288fd3
to
a2618bc
Compare
a2618bc
to
3148fad
Compare
* | ||
* @param string $xpath An XPath expression | ||
* | ||
* @return array|Crawler An array of evaluation results or a new Crawler instance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
returning an array of a Crawler makes it difficult to work with this method in a fluent interface. This would be the first method returning a Crawler or something else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I thought twice before defining the return type. I also don't like it but the DOMXPath::evaluate()
returns a simple type value or DOMNodeList. The result depends on the type of xpath query. I figured that the end user knows what it's gonna be since he wrote the query.
Not sure how we could solve it differently (other than defining two methods and verifying results, or forbidding one type of queries).
+1 👍 |
Thank you @jakzal. |
…on (jakzal) This PR was merged into the 3.2-dev branch. Discussion ---------- [DomCrawler] Add support for XPath expression evaluation | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #19162 | License | MIT | Doc PR | TODO Example usage: ```php <?php use Symfony\Component\DomCrawler\Crawler; use Symfony\Component\VarDumper\VarDumper; require_once __DIR__.'/vendor/autoload.php'; $html = '<html> <body> <span id="article-100" class="article">Article 1</span> <span id="article-101" class="article">Article 2</span> <span id="article-102" class="article">Article 3</span> </body> </html>'; $crawler = new Crawler(); $crawler->addHtmlContent($html); VarDumper::dump($crawler->filterXPath('//span[contains(@id, "article-")]')->evaluate('substring-after(@id, "-")')); // array:3 [ // 0 => "100" // 1 => "101" // 2 => "102" // ] VarDumper::dump($crawler->evaluate('substring-after(//span[contains(@id, "article-")]/@id, "-")')); // array:1 [ // 0 => "100" // ] VarDumper::dump($crawler->filterXPath('//span[@Class="article"]')->evaluate('count(@id)')); // array:3 [ // 0 => 1.0 // 1 => 1.0 // 2 => 1.0 // ] VarDumper::dump($crawler->evaluate('count(//span[@Class="article"])')); // array:1 [ // 0 => 3.0 // ] VarDumper::dump($crawler->evaluate('//span[1]')); // Symfony\Component\DomCrawler\Crawler { } ``` Commits ------- 3148fad [DomCrawler] Add support for XPath expression evaluation
This PR was merged into the master branch. Discussion ---------- [DomCrawler] Document XPath expression evaluation Documents symfony/symfony#19430 Commits ------- 156b047 [DomCrawler] Document XPath expression evaluation
Example usage: