fix axes handling in Crawler::filterXPath()
Due to some limitations in the relativize() method, it was not possible to use XPath axes other than descendant or descendant-or-self in the filterXPath() method of the Crawler class. This commit adds support for the ancestor, ancestor-or-self, attribute, child, following, following-sibling, parent, preceding, preceding-sibling and self axes.
This commit is contained in:
parent
cd005e69ff
commit
8dc322be34
@ -854,7 +854,7 @@ class Crawler extends \SplObjectStorage
|
||||
$expression = $nonMatchingExpression;
|
||||
} elseif (0 === strpos($expression, 'descendant::')) {
|
||||
$expression = 'descendant-or-self::' . substr($expression, strlen('descendant::'));
|
||||
} elseif (0 !== strpos($expression, 'descendant-or-self::')) {
|
||||
} elseif (!preg_match('/^(ancestor|ancestor-or-self|attribute|child|descendant-or-self|following|following-sibling|parent|preceding|preceding-sibling|self)::/', $expression)) {
|
||||
$expression = 'self::' .$expression;
|
||||
}
|
||||
$expressions[] = $parenthesis.$expression;
|
||||
|
@ -411,6 +411,74 @@ EOF
|
||||
$this->assertCount(3, $crawler->filterXPath('//body')->filterXPath('//button')->parents(), '->filterXpath() preserves parents when chained');
|
||||
}
|
||||
|
||||
public function testFilterXPathWithAncestorAxis()
|
||||
{
|
||||
$crawler = $this->createTestCrawler()->filterXPath('//form');
|
||||
|
||||
$this->assertCount(2, $crawler->filterXPath('ancestor::*'));
|
||||
}
|
||||
|
||||
public function testFilterXPathWithAncestorOrSelfAxis()
|
||||
{
|
||||
$crawler = $this->createTestCrawler()->filterXPath('//form');
|
||||
|
||||
$this->assertCount(3, $crawler->filterXPath('ancestor-or-self::*'));
|
||||
}
|
||||
|
||||
public function testFilterXPathWithAttributeAxis()
|
||||
{
|
||||
$crawler = $this->createTestCrawler()->filterXPath('//form');
|
||||
|
||||
$this->assertCount(2, $crawler->filterXPath('attribute::*'));
|
||||
}
|
||||
|
||||
public function testFilterXPathWithChildAxis()
|
||||
{
|
||||
$crawler = $this->createTestCrawler()->filterXPath('//body');
|
||||
|
||||
$this->assertCount(2, $crawler->filterXPath('child::input'));
|
||||
}
|
||||
|
||||
public function testFilterXPathWithFollowingAxis()
|
||||
{
|
||||
$crawler = $this->createTestCrawler()->filterXPath('//a');
|
||||
|
||||
$this->assertCount(3, $crawler->filterXPath('following::div'));
|
||||
}
|
||||
|
||||
public function testFilterXPathWithFollowingSiblingAxis()
|
||||
{
|
||||
$crawler = $this->createTestCrawler()->filterXPath('//a');
|
||||
|
||||
$this->assertCount(2, $crawler->filterXPath('following-sibling::div'));
|
||||
}
|
||||
|
||||
public function testFilterXPathWithParentAxis()
|
||||
{
|
||||
$crawler = $this->createTestCrawler()->filterXPath('//button');
|
||||
|
||||
$this->assertEquals('foo', $crawler->filterXPath('parent::*')->attr('action'));
|
||||
}
|
||||
|
||||
public function testFilterXPathWithPrecedingAxis()
|
||||
{
|
||||
$crawler = $this->createTestCrawler()->filterXPath('//form');
|
||||
|
||||
$this->assertCount(13, $crawler->filterXPath('preceding::*'));
|
||||
}
|
||||
|
||||
public function testFilterXPathWithPrecedingSiblingAxis()
|
||||
{
|
||||
$crawler = $this->createTestCrawler()->filterXPath('//form');
|
||||
|
||||
$this->assertCount(9, $crawler->filterXPath('preceding-sibling::*'));
|
||||
}
|
||||
|
||||
public function testFilterXPathWithSelfAxes()
|
||||
{
|
||||
$this->assertCount(1, $this->createTestCrawler()->filterXPath('self::*'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DomCrawler\Crawler::filter
|
||||
*/
|
||||
|
Reference in New Issue
Block a user