diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index f7edbd7b64450..8e5db3cc66d07 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -487,13 +487,14 @@ public function extract($attributes) /** * Filters the list of nodes with an XPath expression. * - * @param string $xpath An XPath expression + * @param string $xpath An XPath expression + * @param array $namespaces An associative array of namespaces that contains (prefix => uri) elements * * @return Crawler A new instance of Crawler with the filtered list of nodes * * @api */ - public function filterXPath($xpath) + public function filterXPath($xpath, array $namespaces = array()) { $document = new \DOMDocument('1.0', 'UTF-8'); $root = $document->appendChild($document->createElement('_root')); @@ -502,6 +503,9 @@ public function filterXPath($xpath) } $domxpath = new \DOMXPath($document); + foreach($namespaces as $prefix => $uri) { + $domxpath->registerNamespace($prefix, $uri); + } return new static($domxpath->query($xpath), $this->uri); } @@ -511,7 +515,8 @@ public function filterXPath($xpath) * * This method only works if you have installed the CssSelector Symfony Component. * - * @param string $selector A CSS selector + * @param string $selector A CSS selector + * @param array $namespaces An associative array of namespaces that contains (prefix => uri) elements * * @return Crawler A new instance of Crawler with the filtered list of nodes * @@ -519,7 +524,7 @@ public function filterXPath($xpath) * * @api */ - public function filter($selector) + public function filter($selector, array $namespaces = array()) { if (!class_exists('Symfony\\Component\\CssSelector\\CssSelector')) { // @codeCoverageIgnoreStart @@ -527,7 +532,7 @@ public function filter($selector) // @codeCoverageIgnoreEnd } - return $this->filterXPath(CssSelector::toXPath($selector)); + return $this->filterXPath(CssSelector::toXPath($selector), $namespaces); } /** diff --git a/tests/Symfony/Tests/Component/DomCrawler/CrawlerTest.php b/tests/Symfony/Tests/Component/DomCrawler/CrawlerTest.php index 403b13a555d38..05be6293dcf7b 100644 --- a/tests/Symfony/Tests/Component/DomCrawler/CrawlerTest.php +++ b/tests/Symfony/Tests/Component/DomCrawler/CrawlerTest.php @@ -244,6 +244,29 @@ public function testFilterXPath() $this->assertEquals(6, count($crawler->filterXPath('//li')), '->filterXPath() filters the node list with the XPath expression'); } + /** + * @covers \Symfony\Component\DomCrawler\Crawler::filterXPath + */ + public function testFilterXPathWithNamespaceSupport() + { + $crawler = $this->createTestCrawlerWithNamespace(); + $this->assertNotSame($crawler, $crawler->filterXPath('yt|accessControl'), '->filterXPath() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->filterXPath() returns a new instance of a crawler'); + + $controls = $crawler->filter('ns1|accessControl', array('ns1' => 'http://namespace.uir.com/schema/')); + $this->assertCount(3, $controls , '->filterXPath() filters the node list with the XPath expression'); + } + + /** + * @expectedException \PHPUnit_Framework_Error_Warning + * @covers \Symfony\Component\DomCrawler\Crawler::filterXPath + */ + public function testFilterXPathWithoutNamespacePassed() + { + $crawler = $this->createTestCrawlerWithNamespace(); + $crawler->filter('ns1|accessControl'); + } + /** * @covers Symfony\Component\DomCrawler\Crawler::filter */ @@ -496,6 +519,20 @@ public function createTestCrawler($uri = null) return new Crawler($dom, $uri); } + public function createTestCrawlerWithNamespace($uri = null) + { + $dom = new \DOMDocument(); + $dom->loadXML(' + + + + + + '); + + return new Crawler($dom, $uri); + } + protected function createDomDocument() { $dom = new \DOMDocument();