diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index c3954946ad83e..c2be6d9348a4d 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -441,7 +441,7 @@ public function parents() $nodes = array(); while ($node = $node->parentNode) { - if (1 === $node->nodeType && '_root' !== $node->nodeName) { + if (1 === $node->nodeType) { $nodes[] = $node; } } @@ -584,15 +584,13 @@ public function extract($attributes) */ public function filterXPath($xpath) { - $document = new \DOMDocument('1.0', 'UTF-8'); - $root = $document->appendChild($document->createElement('_root')); + $crawler = new static(null, $this->uri); foreach ($this as $node) { - $root->appendChild($document->importNode($node, true)); + $domxpath = new \DOMXPath($node->ownerDocument); + $crawler->add($domxpath->query($xpath, $node)); } - $domxpath = new \DOMXPath($document); - - return new static($domxpath->query($xpath), $this->uri); + return $crawler; } /** diff --git a/src/Symfony/Component/DomCrawler/Field/FormField.php b/src/Symfony/Component/DomCrawler/Field/FormField.php index 6412272c2e294..27fb5f06a8a8f 100644 --- a/src/Symfony/Component/DomCrawler/Field/FormField.php +++ b/src/Symfony/Component/DomCrawler/Field/FormField.php @@ -52,13 +52,7 @@ public function __construct(\DOMNode $node) { $this->node = $node; $this->name = $node->getAttribute('name'); - - $this->document = new \DOMDocument('1.0', 'UTF-8'); - $this->node = $this->document->importNode($this->node, true); - - $root = $this->document->appendChild($this->document->createElement('_root')); - $root->appendChild($this->node); - $this->xpath = new \DOMXPath($this->document); + $this->xpath = new \DOMXPath($node->ownerDocument); $this->initialize(); } diff --git a/src/Symfony/Component/DomCrawler/Form.php b/src/Symfony/Component/DomCrawler/Form.php index 2649d6d33b30c..03f6980b34e10 100644 --- a/src/Symfony/Component/DomCrawler/Form.php +++ b/src/Symfony/Component/DomCrawler/Form.php @@ -378,9 +378,7 @@ private function initialize() { $this->fields = new FormFieldRegistry(); - $document = new \DOMDocument('1.0', 'UTF-8'); - $xpath = new \DOMXPath($document); - $root = $document->appendChild($document->createElement('_root')); + $xpath = new \DOMXPath($this->node->ownerDocument); // add submitted button if it has a valid name if ('form' !== $this->button->nodeName && $this->button->hasAttribute('name') && $this->button->getAttribute('name')) { @@ -390,39 +388,33 @@ private function initialize() // temporarily change the name of the input node for the x coordinate $this->button->setAttribute('name', $name.'.x'); - $this->set(new Field\InputFormField($document->importNode($this->button, true))); + $this->set(new Field\InputFormField($this->button)); // temporarily change the name of the input node for the y coordinate $this->button->setAttribute('name', $name.'.y'); - $this->set(new Field\InputFormField($document->importNode($this->button, true))); + $this->set(new Field\InputFormField($this->button)); // restore the original name of the input node $this->button->setAttribute('name', $name); - } - else { - $this->set(new Field\InputFormField($document->importNode($this->button, true))); + } else { + $this->set(new Field\InputFormField($this->button)); } } // find form elements corresponding to the current form if ($this->node->hasAttribute('id')) { - // traverse through the whole document - $node = $document->importNode($this->node->ownerDocument->documentElement, true); - $root->appendChild($node); - // corresponding elements are either descendants or have a matching HTML5 form attribute $formId = Crawler::xpathLiteral($this->node->getAttribute('id')); - $fieldNodes = $xpath->query(sprintf('descendant::input[@form=%s] | descendant::button[@form=%s] | descendant::textarea[@form=%s] | descendant::select[@form=%s] | //form[@id=%s]//input[not(@form)] | //form[@id=%s]//button[not(@form)] | //form[@id=%s]//textarea[not(@form)] | //form[@id=%s]//select[not(@form)]', $formId, $formId, $formId, $formId, $formId, $formId, $formId, $formId), $root); + + // do the xpath query without $this->node as the context node (i.e. traverse through the whole document) + $fieldNodes = $xpath->query(sprintf('descendant::input[@form=%s] | descendant::button[@form=%s] | descendant::textarea[@form=%s] | descendant::select[@form=%s] | //form[@id=%s]//input[not(@form)] | //form[@id=%s]//button[not(@form)] | //form[@id=%s]//textarea[not(@form)] | //form[@id=%s]//select[not(@form)]', $formId, $formId, $formId, $formId, $formId, $formId, $formId, $formId)); foreach ($fieldNodes as $node) { $this->addField($node); } } else { - // parent form has no id, add descendant elements only - $node = $document->importNode($this->node, true); - $root->appendChild($node); - - // descendant elements with form attribute are not part of this form - $fieldNodes = $xpath->query('descendant::input[not(@form)] | descendant::button[not(@form)] | descendant::textarea[not(@form)] | descendant::select[not(@form)]', $root); + // do the xpath query with $this->node as the context node, to only find descendant elements + // however, descendant elements with form attribute are not part of this form + $fieldNodes = $xpath->query('descendant::input[not(@form)] | descendant::button[not(@form)] | descendant::textarea[not(@form)] | descendant::select[not(@form)]', $this->node); foreach ($fieldNodes as $node) { $this->addField($node); } diff --git a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php index 1c223980252fd..867b24613c0ae 100644 --- a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php @@ -378,8 +378,10 @@ public function testFilterXPath() $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->filterXPath() returns a new instance of a crawler'); $crawler = $this->createTestCrawler()->filterXPath('//ul'); - $this->assertCount(6, $crawler->filterXPath('//li'), '->filterXPath() filters the node list with the XPath expression'); + + $crawler = $this->createTestCrawler(); + $this->assertCount(3, $crawler->filterXPath('//body')->filterXPath('//button')->parents(), '->filterXpath() preserves parents when chained'); } /** pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy