xdv

Cannot compile descendant XPath expression generated by CSS selector

Bug #657968 reported by Martin Aspeli
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
lxml
Fix Released
Medium
Unassigned
xdv
New
Undecided
Unassigned

Bug Description

Using this rule:

<drop css:content="dl.portletNavigationTree a img" />

I get this error:

XSLTParseError: xsltCompilePattern : failed to compile '//dl[contains(concat(' ', normalize-space(@class), ' '), ' portletNavigationTree ')]/descendant::a/descendant::img'

This expression would work:

//dl[contains(concat(' ', normalize-space(@class), ' '), ' portletNavigationTree ')]//a//img

Revision history for this message
Laurence Rowe (lrowe) wrote :

xsl:template match is more restrictive than plain xpath: http://www.w3.org/TR/xslt#Patterns
"The syntax for patterns is a subset of the syntax for expressions. In particular, location paths that meet certain restrictions can be used as patterns."
"A Pattern is a set of location path patterns separated by |. A location path pattern is a location path whose steps all use only the child or attribute axes. Although patterns must not use the descendant-or-self axis, patterns may use the // operator as well as the / operator."

A minimal test case here would be "body a":

>>> from lxml import etree, cssselect
>>> match = cssselect.css_to_xpath('body a', '//')
>>> match
u'//body/descendant::a'
>>> doc = etree.XML('''<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match=""/></xsl:stylesheet>''')
>>> template = doc.getchildren()[0]
>>> template.set('match', match)
>>> etree.XSLT(doc)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "xslt.pxi", line 399, in lxml.etree.XSLT.__init__ (src/lxml/lxml.etree.c:108752)
XSLTParseError: xsltCompilePattern : failed to compile '//body/descendant::a'

I guess we should probably file this as a bug report against lxml.

Laurence

Revision history for this message
scoder (scoder) wrote :

The cssselect.py module was not designed to work with XSLT specifically. It's meant as a translator to general XPath expressions.

I would accept a patch that simplifies the XPath expressions without changing their behaviour.

Changed in lxml:
importance: Undecided → Low
status: New → Confirmed
Revision history for this message
Laurence Rowe (lrowe) wrote :

Make css_to_xpath more compatible with location paths.

In lxml.cssselect, use the xpath 'A//B' (short for 'A/descendant-or-self::node()/B') instead of 'A/descendant::B' for the css descendant selector ('A B'). This makes a few edge cases to be consistent with the selector behavior in WebKit and Firefox, and makes more css
expressions valid location paths (for use in xsl:template match).

https://github.com/lxml/lxml/pull/1

Revision history for this message
scoder (scoder) wrote :

Pull request was merged. Thanks.

Changed in lxml:
importance: Low → Medium
status: Confirmed → Fix Committed
Revision history for this message
scoder (scoder) wrote :

Fixed in lxml 2.3.1.

Changed in lxml:
milestone: none → 2.3.1
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.