ZF-10856: Zend_Dom_Query problem with css selector which contains dots in attribute selector
Description
Lets have xml file like this http://pastie.org/1338299 and try to do this http://pastie.org/1338306, we get error "Fatal error: Call to a member function item() on a non-object in Zend\Dom\Query\Result.php on line 150".
Generated Xpath query is //tv//programme[@channel='cnn[contains(concat(' ', normalize-space(@class), ' '), ' tv ')][contains(concat(' ', normalize-space(@class), ' '), ' gonix ')][contains(concat(' ', normalize-space(@class), ' '), ' net ')]'].
With Xpath query '//tv//programme[@channel="cnn.tv.gonix.net"]' ($query->queryXpath()) it works perfect.
Here is the unit test to use with http://pastie.org/1338299 file
Index: D:/Libraries/ZendFramework/svn/tests/Zend/Dom/QueryTest.php
--- D:/Libraries/ZendFramework/svn/tests/Zend/Dom/QueryTest.php (revision 23462)
+++ D:/Libraries/ZendFramework/svn/tests/Zend/Dom/QueryTest.php (working copy)
@@ -311,6 +311,15 @@
$this->assertType('DOMDocument', $doc);
$this->assertEquals('utf-8', $doc->encoding);
}
+
+ public function testAttributeDotCssSelectorOnXmlDocument()
+ {
+ $file = file_get_contents(dirname(FILE) . '/_files/xml.xml');
+ $this->query->setDocument($file);
+ $result = $this->query->query('tv programme[channel="cnn.tv.gonix.net"]');
+ $this->assertEqual($result->count(), 3);
+ $this->assertEqual($result->current()->getElementsByTagName('title')->item(0)->nodeValue, 'Connect the World with Becky Anderson');
+ }
}
// Call Zend_Dom_QueryTest::main() if this source file is executed directly.
Comments
Posted by Matthew Weier O'Phinney (matthew) on 2010-12-20T11:26:18.000+0000
I'll see what I can do. Likely, however, the only way to address this would be to write a full CSS selector parser -- the current incarnation is not at all context-aware and relies heavily on fast operations such as str_replace().
Posted by Sasa Stamenkovic (umpirsky) on 2010-12-20T12:23:09.000+0000
There is https://github.com/symfony/symfony/… which have cssToXpath(). This component is a port of the Python lxml library, which is copyright Infrae and distributed under the BSD license. Didn't try this, but if it works, maybe sth can be learned from there.