Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0bc09b8

Browse files
committed
Add a way to filter direct children
1 parent f0168e3 commit 0bc09b8

File tree

2 files changed

+59
-6
lines changed

2 files changed

+59
-6
lines changed

src/Symfony/Component/DomCrawler/Crawler.php

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -501,16 +501,26 @@ public function parents()
501501
/**
502502
* Returns the children nodes of the current selection.
503503
*
504+
* @param $selector string|null A optional CSS selector to filter children
505+
*
504506
* @return self
505507
*
506508
* @throws \InvalidArgumentException When current node is empty
509+
* @throws \RuntimeException if the CssSelector Component is not available and $selector is provided
507510
*/
508-
public function children()
511+
public function children($selector = null)
509512
{
510513
if (!$this->nodes) {
511514
throw new \InvalidArgumentException('The current node list is empty.');
512515
}
513516

517+
if ($selector) {
518+
$converter = $this->createCssSelectorConverter($this->isHtml);
519+
$xpath = $converter->toXPath($selector, 'child::*/');
520+
521+
return $this->filterXPath($xpath);
522+
}
523+
514524
$node = $this->getNode(0)->firstChild;
515525

516526
return $this->createSubCrawler($node ? $this->sibling($node) : array());
@@ -691,11 +701,7 @@ public function filterXPath($xpath)
691701
*/
692702
public function filter($selector)
693703
{
694-
if (!class_exists(CssSelectorConverter::class)) {
695-
throw new \RuntimeException('To filter with a CSS selector, install the CssSelector component ("composer require symfony/css-selector"). Or use filterXpath instead.');
696-
}
697-
698-
$converter = new CssSelectorConverter($this->isHtml);
704+
$converter = $this->createCssSelectorConverter($this->isHtml);
699705

700706
// The CssSelector already prefixes the selector with descendant-or-self::
701707
return $this->filterRelativeXPath($converter->toXPath($selector));
@@ -1148,4 +1154,20 @@ private function createSubCrawler($nodes)
11481154

11491155
return $crawler;
11501156
}
1157+
1158+
/**
1159+
* @param bool $html Whether HTML support should be enabled. Disable it for XML documents
1160+
*
1161+
* @return CssSelectorConverter A CssSelectorConverter instance
1162+
*
1163+
* @throws \RuntimeException if the CssSelector Component is not available
1164+
*/
1165+
private function createCssSelectorConverter(bool $isHtml)
1166+
{
1167+
if (!class_exists(CssSelectorConverter::class)) {
1168+
throw new \RuntimeException('To filter with a CSS selector, install the CssSelector component ("composer require symfony/css-selector"). Or use filterXpath instead.');
1169+
}
1170+
1171+
return new CssSelectorConverter($isHtml);
1172+
}
11511173
}

src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,37 @@ public function testChildren()
10041004
}
10051005
}
10061006

1007+
public function testFilteredChildren()
1008+
{
1009+
$html = <<<'HTML'
1010+
<!DOCTYPE html>
1011+
<html lang="en">
1012+
<body>
1013+
<div id="foo">
1014+
<div class="lorem">
1015+
<p class="lorem"></p>
1016+
</div>
1017+
<div class="lorem">
1018+
<span class="lorem"></span>
1019+
</div>
1020+
<span class="ipsum"></span>
1021+
</div>
1022+
</body>
1023+
</html>
1024+
HTML;
1025+
1026+
$crawler = new Crawler($html);
1027+
$foo = $crawler->filter('#foo');
1028+
1029+
$this->assertEquals(3, $foo->children()->count());
1030+
$this->assertEquals(2, $foo->children('.lorem')->count());
1031+
$this->assertEquals(2, $foo->children('div')->count());
1032+
$this->assertEquals(2, $foo->children('div.lorem')->count());
1033+
$this->assertEquals(1, $foo->children('span')->count());
1034+
$this->assertEquals(1, $foo->children('span.ipsum')->count());
1035+
$this->assertEquals(1, $foo->children('.ipsum')->count());
1036+
}
1037+
10071038
public function testParents()
10081039
{
10091040
$crawler = $this->createTestCrawler()->filterXPath('//li[1]');

0 commit comments

Comments
 (0)