# -*- coding:utf-8 -*- # # Copyright (C) 2008 - Olivier Lauzanne # # Distributed under the BSD license, see LICENSE.txt from __future__ import unicode_literals from cssselect import xpath as cssselect_xpath from cssselect.xpath import ExpressionError XPathExprOrig = cssselect_xpath.XPathExpr class XPathExpr(XPathExprOrig): def __init__(self, path='', element='*', condition='', star_prefix=False): self.path = path self.element = element self.condition = condition self.post_condition = None def add_post_condition(self, post_condition): if self.post_condition: self.post_condition = '%s and (%s)' % (self.post_condition, post_condition) else: self.post_condition = post_condition def __str__(self): path = XPathExprOrig.__str__(self) if self.post_condition: path = '%s[%s]' % (path, self.post_condition) return path def join(self, combiner, other): res = XPathExprOrig.join(self, combiner, other) self.post_condition = other.post_condition return res # keep cssselect < 0.8 compat for now class JQueryTranslator(cssselect_xpath.HTMLTranslator): """This class is used to implement the css pseudo classes (:first, :last, ...) that are not defined in the css standard, but are defined in the jquery API. """ xpathexpr_cls = XPathExpr def xpath_first_pseudo(self, xpath): """Matches the first selected element:: >>> from pyquery import PyQuery >>> d = PyQuery('

') >>> d('p:first') [] .. """ xpath.add_post_condition('position() = 1') return xpath def xpath_last_pseudo(self, xpath): """Matches the last selected element:: >>> from pyquery import PyQuery >>> d = PyQuery('

') >>> d('p:last') [] .. """ xpath.add_post_condition('position() = last()') return xpath def xpath_even_pseudo(self, xpath): """Matches even elements, zero-indexed:: >>> from pyquery import PyQuery >>> d = PyQuery('

') >>> d('p:even') [

] .. """ # the first element is 1 in xpath and 0 in python and js xpath.add_post_condition('position() mod 2 = 1') return xpath def xpath_odd_pseudo(self, xpath): """Matches odd elements, zero-indexed:: >>> from pyquery import PyQuery >>> d = PyQuery('

') >>> d('p:odd') [] .. """ xpath.add_post_condition('position() mod 2 = 0') return xpath def xpath_checked_pseudo(self, xpath): """Matches odd elements, zero-indexed:: >>> from pyquery import PyQuery >>> d = PyQuery('
') >>> d('input:checked') [] .. """ xpath.add_condition("@checked and name(.) = 'input'") return xpath def xpath_selected_pseudo(self, xpath): """Matches all elements that are selected:: >>> from pyquery import PyQuery >>> d = PyQuery('') >>> d('option:selected') [