> from lxml import etree > > class XMLable: > cname= '' > Text= object() > class CTor: > def __init__( self, *ar ): > self.ar, self.kwar= ar, dict( ar ) > ctor= CTor() > FTor= dict > ftor= {} > def __init__( self, par= None, *ar, **kwar ): > nsmap= kwar.pop( 'nsmap', None ) > if par is None: > self.node= etree.Element( self.cname or > self.__class__.__name__, > nsmap= nsmap ) > else: > self.node= etree.SubElement( par.node, self.cname or > self.__class__.__name__, nsmap= nsmap ) > for a, ca in zip( ar, self.ctor.ar ): > if ca[0] in self.ftor: > a= self.ftor[ ca[0] ]( a ) > if ca[1] is XMLable.Text: > self.node.text= a > else: > self.node.set( ca[1], a ) > for k, v in kwar.items(): > if k in self.ftor: > v= self.ftor[ k ]( v ) > if self.ctor.kwar[ k ] is XMLable.Text: > self.node.text= v > else: > self.node.set( self.ctor.kwar[ k ], str( v ) ) > > SS= '{urn:schemas-microsoft-com:office:spreadsheet}' > X= '{urn:schemas-microsoft-com:office:excel}' > > class Workbook( XMLable ): > #jtor= JTor( 'xmlns', req= 'urn:schemas-microsoft- > com:office:spreadsheet' ) > def __init__( self ): > nns= { 'x': 'urn:schemas-microsoft-com:office:excel', > 'ss': 'urn:schemas-microsoft-com:office:spreadsheet' } > XMLable.__init__( self, nsmap= nns ) > self.node.set( 'xmlns', 'urn:schemas-microsoft- > com:office:spreadsheet' ) > self.styles= Styles( self ) > class Worksheet( XMLable ): > ctor= XMLable.CTor( ( 'name', SS+ 'Name' ) ) > class Table( XMLable ): pass > class Row( XMLable ): > ctor= XMLable.CTor( ( 'index', SS+ 'Index' ) ) > class Cell( XMLable ): > ctor= XMLable.CTor( ( 'index', SS+ 'Index' ), ( 'style', SS+ > 'StyleID' ) ) > ftor= XMLable.FTor( { 'style': lambda x: x.styleid } ) > class Data( XMLable ): > ctor= XMLable.CTor( ( 'type', SS+ 'Type' ), ( 'data', > XMLable.Text ) ) > class Styles( XMLable ): pass > class Font( XMLable ): > #jtor= JTor( 'family', X+ 'Family', req='Swiss' ), Jtor( 'bold', SS+ > 'Bold', lambda x: str( int( x ) ) ) > ctor= XMLable.CTor( ( 'family', X+ 'Family' ), ( 'bold', SS+ > 'Bold' ) ) > ftor= XMLable.FTor( { 'bold': lambda x: str( int( x ) ) } ) > class Style( XMLable ): > styles= {} > ctor= XMLable.CTor( ( 'styleid', SS+ 'ID' ) ) > def __init__( self, par= None, *ar, **kwar ): > self.styleid= 's%i'% ( 21+ len( Style.styles ) ) > Style.styles[ self.styleid ]= self > XMLable.__init__( self, par.styles, self.styleid ) > Font( self, *ar, **kwar ) > > book= Workbook() > sheet= Worksheet( book, 'WSheet1' ) > table= Table( sheet ) > row= Row( table, index= '2' ) > style= Style( book, 'Swiss', True ) > celli= Cell( row, style= style ) > datai= Data( celli, 'Number', '123' ) > cellj= Cell( row, index= 3 ) > dataj= Data( cellj, 'String', 'abc' ) > > out= etree.tostring( book.node, pretty_print= True, > xml_declaration=True ) > print( out ) > open( 'xl.xml', 'w' ).write( out ) > new= etree.XML( out ) > etree.XML( etree.tostring( book.node ) ) > out= etree.tostring( new, pretty_print= True, xml_declaration=True ) > print( out )
This is one way of eliminating a particular redundancy that showed up in the first implementation. I've already excluded some potential uses of XMLable. I've, in other words, made assumptions. -- http://mail.python.org/mailman/listinfo/python-list