TurboXML

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Costi
User
Beiträge: 544
Registriert: Donnerstag 17. August 2006, 14:21

TurboXML

Beitragvon Costi » Donnerstag 6. September 2007, 21:22

noch nie hats sowiel spass gemacht XML dateien zu schreiben:

:shock: :D :shock: :D :shock: :D :shock:

Code: Alles auswählen

class TurboXML(object):
   def __init__(self):
      self.last_tags = []
      self.data = ''
      self.complete_tag = False
   
   def _mtc(self):#_manage_tag_completeation
      if self.complete_tag == None: #with a slash
         return ' />'
      elif self.complete_tag == True:
         return '>'
      elif self.complete_tag == False:
         return ''
      assert False
   
   def exe(self, cmd):
      if  cmd.startswith('end'):
         if not self.last_tags:
            raise NameError, 'all tags are already closed'
         elif len(cmd) > 3 and cmd[3:] != self.last_tags[-1]:
            raise ValueError, 'closing the tag "%s" would result in invalid XML' % cmd[3:]

         self.data += '%s</%s>' % (self._mtc(), self.last_tags.pop())
         self.complete_tag = False
   
      elif cmd.endswith("_"):
            self.data += "%s<%s" % (self._mtc(), cmd[:-1])
            self.complete_tag = None #with a slash
            return self
      else:
         
         self.data += "%s<%s" % (self._mtc(), cmd)
         self.complete_tag = True
         
         self.last_tags.append(cmd)
         return self
      return self

   def __getattr__(self, attr):
      return self.exe(attr)
   
   def __call__(self, text=None, **args):
      if text == None:
         #fuegt die argumente hinzu
         self.data += " %s%s" % (' '.join(['%s="%s"'%(key, value.__str__()) for key, value in args.iteritems()]), self._mtc())
         self.complete_tag = False #sollte schon so True sein
         return self
      else:
         #schreiben
         self.data += '%s%s' % (self._mtc(), text) #evtl escape html      
         self.complete_tag = False
         return self


   def __str__(self):
      return self.data + self._mtc()




if __name__ == "__main__":
   page = TurboXML()
   page.html.head.title('helo world').end.endhead.body(bgcolor='red')
   [getattr(page, 'h'+str(i+1))('halo welt in schriftgroesse ' + str(i+1)).end.br_('\n') for i in range(7)]
   page.endbody.endhtml

   print page
   
   #=====output
   #<html><head><title>helo world</title></head><body bgcolor="red"><h0>halo welt in schriftgroesse 0</h0><br />
   #<h1>halo welt in schriftgroesse 1</h1><br />
   #<h2>halo welt in schriftgroesse 2</h2><br />
   #<h3>halo welt in schriftgroesse 3</h3><br />
   #<h4>halo welt in schriftgroesse 4</h4><br />
   #<h5>halo welt in schriftgroesse 5</h5><br />
   #<h6>halo welt in schriftgroesse 6</h6><br />
   #<h7>halo welt in schriftgroesse 7</h7><br />
   #</body></html>
cp != mv
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 6. September 2007, 22:03

Da ``None`` ein Singleton ist, testet man nach Identität und nicht nach Gleichheit. Außerdem wird die Syntax ``raise Exception, "Text"`` in python 3.0 rausfallen und ich würde sie schon jetzt nicht mehr benutzen. Namen (zudem welche ohne Docstring) wie ``_mtc`` agen einem gar nichts. Die einrückung ist teilweise ziemlich wild, siehe Zeile 27-28.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Re: TurboXML

Beitragvon gerold » Donnerstag 6. September 2007, 22:34

Costi hat geschrieben:noch nie hats sowiel spass gemacht

Hallo!

Python ist so richtig schön flexibel. Das sieht man besonders gut an solchen Codeschnipseln. :-)

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Costi
User
Beiträge: 544
Registriert: Donnerstag 17. August 2006, 14:21

Beitragvon Costi » Freitag 7. September 2007, 23:31

hier ne neue version.......
(achtung: nur spaerlich getestet)

Code: Alles auswählen


class TurboXML(object):
   def __init__(self):
      self.data = {}
      self.data['main'] = ''
      self.write_on = 'main'
      self.balanced = True
      self.last_tags = []
   def __call__(self, text=None, **kw):
      if text is None:
         self.balanced = True
         self(' %s>' % ' '.join(['%s="%s"'%(key, value.__str__()) for key, value in kw.iteritems()]))
      else:
         #write
         if self.balanced:
            t = ''
         else:
            t = '>'
            self.balanced = True
         self.data[self.write_on] += '%s%s' % (t, text)
      return self
   def exe(self, cmd):
      
      #xml is case insensitive (oder?)
      cmd = cmd.lower()
      
      if cmd == 'end_block':
         self.write_on = 'main'
      elif cmd == 'end':
         self('</%s>' % self.last_tags.pop())
      elif cmd.startswith('end_'):
         tag = self.last_tags.pop()
         if tag != cmd[4:]:
            raise ValueError('closing the tag "%s" now would result in invalid XML' % cmd[4:])
         self('</%s>' % tag)
      elif cmd.endswith('_'):
         self('<%s />' % cmd[:-1])
      elif cmd.startswith('block_'):
         block_name = cmd[6:]
         if block_name.startswith('_'):
            raise ValueError('sory, blocks starting with "_" are only for internal use')
         
         if not '<>%s<>' % block_name in self.data['main']:
            self('<>%s<>' % block_name)
         
         self.data[block_name] = ''
         self.write_on = block_name
      else:
         self('<%s' % cmd)
         self.balanced = False
         self.last_tags.append(cmd)
      return self
   def __getattr__(self, attr):
      return self.exe(attr)
         
   def compile(self):
      'apply all blocks, except the ones used by a procedure (aka starting with "_")'
      self('')
      del_after_iter = []
      data_keys = self.data.keys()
      for key, value in self.data.iteritems():
         if key != 'main' and not key.startswith('_') and not '_' + key in data_keys: # es darf keine procedure sein
               self.data['main'] = self.data['main'].replace('<>%s<>'%key, value)
               del_after_iter.append(key)
      for key in del_after_iter: del self.data[key]
      
   def __str__(self):
      self('')
      retval = self.data['main']
      
      for key, value in self.data.iteritems():
         if key != 'main' and not key.startswith('_'):
            retval = retval.replace('<>%s<>'%key, value)
      return retval
   

   def create_procedure(self, name, callback):
      getattr(self, 'block_' + name)
      self.end_block
      self.data['_'+name] = callback
   def call_procedure(self, name, *args, **kwargs):
      #self.data[name] += self.data['_' + name](*args, **kwargs)
      old_write_on = self.write_on
      self.write_on = name
      
      self.data['_' + name](*args, **kwargs)
      
      self.write_on = old_write_on
         


if __name__ == "__main__":
   page = TurboXML()
   page.html.head.title('helo world').end.end_head.body(bgcolor='red')
   page.create_procedure('halo', lambda n: page.b("halo welt in schriftgroesse " + n).end_b)
   page.end_body.block_test('testing...').end_block.end_html
   
   page.block_test.b("testing2").end.end_block
   page.compile()
   page.call_procedure('halo', n='7')
   page.call_procedure('halo', n='2')
   print page
   #output
   #<html><head><title>helo world</title></head><body bgcolor="red"><b>halo welt in schriftgroesse 7</b><b>halo welt in schriftgroesse 2</b></body><b>testing2</b></html>






cp != mv

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder