Skip to content

Commit

Permalink
[DomCrawler] Fixed an issue with namespace prefix matching being to g…
Browse files Browse the repository at this point in the history
…reedy.

The regexp matching prefixes is naive and matches most of strings followed by a colon. It is also incomplete as it does not match all the supported characters (like the unicode ones). It is simple though and sufficient in most situations.
  • Loading branch information
jakzal committed Sep 25, 2013
1 parent 55de9d9 commit 3292163
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 13 deletions.
8 changes: 4 additions & 4 deletions src/Symfony/Component/DomCrawler/Crawler.php
Expand Up @@ -835,7 +835,9 @@ private function createDOMXPath(\DOMDocument $document, array $prefixes = array(

foreach ($prefixes as $prefix) {
$namespace = $this->discoverNamespace($domxpath, $prefix);
$domxpath->registerNamespace($prefix, $namespace);
if (null !== $namespace) {
$domxpath->registerNamespace($prefix, $namespace);
}
}

return $domxpath;
Expand All @@ -861,8 +863,6 @@ private function discoverNamespace(\DOMXPath $domxpath, $prefix)
if ($node = $namespaces->item(0)) {
return $node->nodeValue;
}

throw new \InvalidArgumentException(sprintf('Could not find a namespace for the prefix: "%s"', $prefix));
}

/**
Expand All @@ -872,7 +872,7 @@ private function discoverNamespace(\DOMXPath $domxpath, $prefix)
*/
private function findNamespacePrefixes($xpath)
{
if (preg_match_all('/(?P<prefix>[a-zA-Z_][a-zA-Z_0-9\-\.]*):[^:]/', $xpath, $matches)) {
if (preg_match_all('/(?P<prefix>[a-z_][a-z_0-9\-\.]*):[^"\/]/i', $xpath, $matches)) {
return array_unique($matches['prefix']);
}

Expand Down
19 changes: 10 additions & 9 deletions src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
Expand Up @@ -401,15 +401,6 @@ public function testFilterXPathWithMultipleNamespaces()
$this->assertSame('widescreen', $crawler->text());
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Could not find a namespace for the prefix: "foo"
*/
public function testFilterXPathWithAnInvalidNamespace()
{
$this->createTestXmlCrawler()->filterXPath('//media:group/foo:aspectRatio');
}

public function testFilterXPathWithManuallyRegisteredNamespace()
{
$crawler = $this->createTestXmlCrawler();
Expand All @@ -420,6 +411,15 @@ public function testFilterXPathWithManuallyRegisteredNamespace()
$this->assertSame('widescreen', $crawler->text());
}

public function testFilterXPathWithAnUrl()
{
$crawler = $this->createTestXmlCrawler();

$crawler = $crawler->filterXPath('//media:category[@scheme="http://gdata.youtube.com/schemas/2007/categories.cat"]');
$this->assertCount(1, $crawler);
$this->assertSame('Music', $crawler->text());
}

/**
* @covers Symfony\Component\DomCrawler\Crawler::filter
*/
Expand Down Expand Up @@ -741,6 +741,7 @@ protected function createTestXmlCrawler($uri = null)
<media:title type="plain">Chordates - CrashCourse Biology #24</media:title>
<yt:aspectRatio>widescreen</yt:aspectRatio>
</media:group>
<media:category label="Music" scheme="http://gdata.youtube.com/schemas/2007/categories.cat">Music</media:category>
</entry>';

return new Crawler($xml, $uri);
Expand Down

0 comments on commit 3292163

Please sign in to comment.