TurboXML

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

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
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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 (former) Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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: 545
Registriert: Donnerstag 17. August 2006, 14:21

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
Antworten