PNG  IHDR* pHYs+ IDATx]n#; cdLb Ǚ[at¤_:uP}>!Usă cag޿ ֵNu`ݼTâabO7uL&y^wFٝA"l[|ŲHLN밪4*sG3|Dv}?+y߉{OuOAt4Jj.u]Gz*҉sP'VQKbA1u\`& Af;HWj hsO;ogTu uj7S3/QzUr&wS`M$X_L7r2;aE+ώ%vikDA:dR+%KzƉo>eOth$z%: :{WwaQ:wz%4foɹE[9<]#ERINƻv溂E%P1i01 |Jvҗ&{b?9g=^wζXn/lK::90KwrюO\!ջ3uzuGv^;騢wq<Iatv09:tt~hEG`v;3@MNZD.1]L:{ծI3`L(÷ba")Y.iljCɄae#I"1 `3*Bdz>j<fU40⨬%O$3cGt]j%Fߠ_twJ;ABU8vP3uEԑwQ V:h%))LfraqX-ۿX]v-\9I gl8tzX ]ecm)-cgʒ#Uw=Wlێn(0hPP/ӨtQ“&J35 $=]r1{tLuǮ*i0_;NƝ8;-vݏr8+U-kruȕYr0RnC]*ެ(M:]gE;{]tg(#ZJ9y>utRDRMdr9㪩̞zֹb<ģ&wzJM"iI( .ꮅX)Qw:9,i좜\Ԛi7&N0:asϓc];=ΗOӣ APqz93 y $)A*kVHZwBƺnWNaby>XMN*45~ղM6Nvm;A=jֲ.~1}(9`KJ/V F9[=`~[;sRuk]rєT!)iQO)Y$V ی ۤmzWz5IM Zb )ˆC`6 rRa}qNmUfDsWuˤV{ Pݝ'=Kֳbg,UҘVz2ﴻnjNgBb{? ߮tcsͻQuxVCIY۠:(V뺕 ٥2;t`@Fo{Z9`;]wMzU~%UA蛚dI vGq\r82iu +St`cR.6U/M9IENDB`"""CSS Selectors based on XPath. This module supports selecting XML/HTML tags based on CSS selectors. See the `CSSSelector` class for details. This is a thin wrapper around cssselect 0.7 or later. """ from __future__ import absolute_import from . import etree try: import cssselect as external_cssselect except ImportError: raise ImportError( 'cssselect does not seem to be installed. ' 'See http://packages.python.org/cssselect/') SelectorSyntaxError = external_cssselect.SelectorSyntaxError ExpressionError = external_cssselect.ExpressionError SelectorError = external_cssselect.SelectorError __all__ = ['SelectorSyntaxError', 'ExpressionError', 'SelectorError', 'CSSSelector'] class LxmlTranslator(external_cssselect.GenericTranslator): """ A custom CSS selector to XPath translator with lxml-specific extensions. """ def xpath_contains_function(self, xpath, function): # Defined there, removed in later drafts: # http://www.w3.org/TR/2001/CR-css3-selectors-20011113/#content-selectors if function.argument_types() not in (['STRING'], ['IDENT']): raise ExpressionError( "Expected a single string or ident for :contains(), got %r" % function.arguments) value = function.arguments[0].value return xpath.add_condition( 'contains(__lxml_internal_css:lower-case(string(.)), %s)' % self.xpath_literal(value.lower())) class LxmlHTMLTranslator(LxmlTranslator, external_cssselect.HTMLTranslator): """ lxml extensions + HTML support. """ def _make_lower_case(context, s): return s.lower() ns = etree.FunctionNamespace('http://codespeak.net/lxml/css/') ns.prefix = '__lxml_internal_css' ns['lower-case'] = _make_lower_case class CSSSelector(etree.XPath): """A CSS selector. Usage:: >>> from lxml import etree, cssselect >>> select = cssselect.CSSSelector("a tag > child") >>> root = etree.XML("TEXT") >>> [ el.tag for el in select(root) ] ['child'] To use CSS namespaces, you need to pass a prefix-to-namespace mapping as ``namespaces`` keyword argument:: >>> rdfns = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' >>> select_ns = cssselect.CSSSelector('root > rdf|Description', ... namespaces={'rdf': rdfns}) >>> rdf = etree.XML(( ... '' ... 'blah' ... '') % rdfns) >>> [(el.tag, el.text) for el in select_ns(rdf)] [('{http://www.w3.org/1999/02/22-rdf-syntax-ns#}Description', 'blah')] """ def __init__(self, css, namespaces=None, translator='xml'): if translator == 'xml': translator = LxmlTranslator() elif translator == 'html': translator = LxmlHTMLTranslator() elif translator == 'xhtml': translator = LxmlHTMLTranslator(xhtml=True) path = translator.css_to_xpath(css) etree.XPath.__init__(self, path, namespaces=namespaces) self.css = css def __repr__(self): return '<%s %s for %r>' % ( self.__class__.__name__, hex(abs(id(self)))[2:], self.css)