<s> __all__ = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] <EOL> from StringIO import StringIO <EOL> import collections <EOL> from lxml import etree <EOL> from bs4 . element import Comment , Doctype , NamespacedAttribute <EOL> from bs4 . builder import ( <EOL> FAST , <EOL> HTML , <EOL> HTMLTreeBuilder , <EOL> PERMISSIVE , <EOL> TreeBuilder , <EOL> XML ) <EOL> from bs4 . dammit import UnicodeDammit <EOL> LXML = '<STR_LIT>' <EOL> class LXMLTreeBuilderForXML ( TreeBuilder ) : <EOL> DEFAULT_PARSER_CLASS = etree . XMLParser <EOL> is_xml = True <EOL> features = [ LXML , XML , FAST , PERMISSIVE ] <EOL> CHUNK_SIZE = <NUM_LIT> <EOL> @ property <EOL> def default_parser ( self ) : <EOL> return etree . XMLParser ( target = self , strip_cdata = False , recover = True ) <EOL> def __init__ ( self , parser = None , empty_element_tags = None ) : <EOL> if empty_element_tags is not None : <EOL> self . empty_element_tags = set ( empty_element_tags ) <EOL> if parser is None : <EOL> parser = self . default_parser <EOL> if isinstance ( parser , collections . Callable ) : <EOL> parser = parser ( target = self , strip_cdata = False ) <EOL> self . parser = parser <EOL> self . soup = None <EOL> self . nsmaps = None <EOL> def _getNsTag ( self , tag ) : <EOL> if tag [ <NUM_LIT:0> ] == '<STR_LIT:{>' : <EOL> return tuple ( tag [ <NUM_LIT:1> : ] . split ( '<STR_LIT:}>' , <NUM_LIT:1> ) ) <EOL> else : <EOL> return ( None , tag ) <EOL> def prepare_markup ( self , markup , user_specified_encoding = None , <EOL> document_declared_encoding = None ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( markup , unicode ) : <EOL> return markup , None , None , False <EOL> try_encodings = [ user_specified_encoding , document_declared_encoding ] <EOL> dammit = UnicodeDammit ( markup , try_encodings , is_html = True ) <EOL> return ( dammit . markup , dammit . original_encoding , <EOL> dammit . declared_html_encoding , <EOL> dammit . contains_replacement_characters ) <EOL> def feed ( self , markup ) : <EOL> if isinstance ( markup , basestring ) : <EOL> markup = StringIO ( markup ) <EOL> data = markup . read ( self . CHUNK_SIZE ) <EOL> self . parser . feed ( data ) <EOL> while data != '<STR_LIT>' : <EOL> data = markup . read ( self . CHUNK_SIZE ) <EOL> if data != '<STR_LIT>' : <EOL> self . parser . feed ( data ) <EOL> self . parser . close ( ) <EOL> def close ( self ) : <EOL> self . nsmaps = None <EOL> def start ( self , name , attrs , nsmap = { } ) : <EOL> attrs = dict ( attrs ) <EOL> nsprefix = None <EOL> if len ( nsmap ) == <NUM_LIT:0> and self . nsmaps != None : <EOL> self . nsmaps . append ( None ) <EOL> elif len ( nsmap ) > <NUM_LIT:0> : <EOL> if self . nsmaps is None : <EOL> self . nsmaps = [ ] <EOL> inverted_nsmap = dict ( ( value , key ) for key , value in nsmap . items ( ) ) <EOL> self . nsmaps . append ( inverted_nsmap ) <EOL> attrs = attrs . copy ( ) <EOL> for prefix , namespace in nsmap . items ( ) : <EOL> attribute = NamespacedAttribute ( <EOL> "<STR_LIT>" , prefix , "<STR_LIT>" ) <EOL> attrs [ attribute ] = namespace <EOL> if self . nsmaps is not None and len ( self . nsmaps ) > <NUM_LIT:0> : <EOL> new_attrs = { } <EOL> for attr , value in attrs . items ( ) : <EOL> namespace , attr = self . _getNsTag ( attr ) <EOL> if namespace is None : <EOL> new_attrs [ attr ] = value <EOL> else : <EOL> nsprefix = self . _prefix_for_namespace ( namespace ) <EOL> attr = NamespacedAttribute ( nsprefix , attr , namespace ) <EOL> new_attrs [ attr ] = value <EOL> attrs = new_attrs <EOL> namespace , name = self . _getNsTag ( name ) <EOL> nsprefix = self . _prefix_for_namespace ( namespace ) <EOL> self . soup . handle_starttag ( name , namespace , nsprefix , attrs ) <EOL> def _prefix_for_namespace ( self , namespace ) : <EOL> """<STR_LIT>""" <EOL> if namespace is None : <EOL> return None <EOL> for inverted_nsmap in reversed ( self . nsmaps ) : <EOL> if inverted_nsmap is not None and namespace in inverted_nsmap : <EOL> return inverted_nsmap [ namespace ] <EOL> def end ( self , name ) : <EOL> self . soup . endData ( ) <EOL> completed_tag = self . soup . tagStack [ - <NUM_LIT:1> ] <EOL> namespace , name = self . _getNsTag ( name ) <EOL> nsprefix = None <EOL> if namespace is not None : <EOL> for inverted_nsmap in reversed ( self . nsmaps ) : <EOL> if inverted_nsmap is not None and namespace in inverted_nsmap : <EOL> nsprefix = inverted_nsmap [ namespace ] <EOL> break <EOL> self . soup . handle_endtag ( name , nsprefix ) <EOL> if self . nsmaps != None : <EOL> self . nsmaps . pop ( ) <EOL> if len ( self . nsmaps ) == <NUM_LIT:0> : <EOL> self . nsmaps = None <EOL> def pi ( self , target , data ) : <EOL> pass <EOL> def data ( self , content ) : <EOL> self . soup . handle_data ( content ) <EOL> def doctype ( self , name , pubid , system ) : <EOL> self . soup . endData ( ) <EOL> doctype = Doctype . for_name_and_ids ( name , pubid , system ) <EOL> self . soup . object_was_parsed ( doctype ) <EOL> def comment ( self , content ) : <EOL> "<STR_LIT>" <EOL> self . soup . endData ( ) <EOL> self . soup . handle_data ( content ) <EOL> self . soup . endData ( Comment ) <EOL> def test_fragment_to_document ( self , fragment ) : <EOL> """<STR_LIT>""" <EOL> return u'<STR_LIT>' % fragment <EOL> class LXMLTreeBuilder ( HTMLTreeBuilder , LXMLTreeBuilderForXML ) : <EOL> features = [ LXML , HTML , FAST , PERMISSIVE ] <EOL> is_xml = False <EOL> @ property <EOL> def default_parser ( self ) : <EOL> return etree . HTMLParser <EOL> def feed ( self , markup ) : <EOL> self . parser . feed ( markup ) <EOL> self . parser . close ( ) <EOL> def test_fragment_to_document ( self , fragment ) : <EOL> """<STR_LIT>""" <EOL> return u'<STR_LIT>' % fragment </s>
