xmlbuilder-1.0/0000775000175000017500000000000011671771754013775 5ustar koderkoder00000000000000xmlbuilder-1.0/xmlbuilder/0000775000175000017500000000000011671771754016144 5ustar koderkoder00000000000000xmlbuilder-1.0/xmlbuilder/__init__.py0000664000175000017500000001720111671770676020260 0ustar koderkoder00000000000000#!/usr/bin/env python #------------------------------------------------------------------------------- import weakref from xml.etree.ElementTree import TreeBuilder, tostring, fromstring #------------------------------------------------------------------------------- __all__ = ["XMLBuilder"] __doc__ = """ XMLBuilder is tiny library build on top of ElementTree.TreeBuilder to make xml files creation more pythonomic. `XMLBuilder` use `with` statement and attribute access to define xml document structure. from __future__ import with_statement # only for python 2.5 from xmlbuilder import XMLBuilder x = XMLBuilder('root') x.some_tag x.some_tag_with_data('text', a='12') with x.some_tree(a='1'): with x.data: x.mmm for i in range(10): x.node(val=str(i)) etree_node = ~x # <= return xml.etree.ElementTree object print str(x) # <= string object will result: text There some fields, which allow xml output customization: formatted = produce formatted xml. default = True tabstep = tab string, used for formatting. default = ' ' * 4 encoding = xml document encoding. default = 'utf-8' xml_header = add xml header () to begining of the document. default = True builder = builder class, used for create dcument. Default = xml.etree.ElementTree.TreeBuilder Options can be readed by x = XMLBuilder('root') print x[option_name] and changed by x[option_name] = new_val Happy xml'ing. """ class XMLNode(object): def __init__(self, doc, tag, *args, **kwargs): self.__document = doc self.__childs = [] self.__tag = tag self.__attrs = {} self.__xml_update(args, kwargs) def __xml_update(self, args, kwargs): for arg in args: if not isinstance(arg, basestring): raise ValueError( "Non-named arguments should be string only, not %r" \ % (arg,)) self.__childs.append("".join(args)) for key, val in kwargs.items(): if not isinstance(val, basestring): raise ValueError( "Attribute values should be string only, not %r" \ % (val,)) self.__attrs.update(kwargs) def __setitem__(self, name, val): if not isinstance(val, basestring): raise ValueError("Attribute names should be string only, not %r" \ % (val,)) if not isinstance(val, basestring): raise ValueError("Attribute values should be string only, not %r" \ % (val,)) self.__attrs[name] = val def __getattr__(self, name): node = XMLNode(self.__document, name) self.__childs.append(node) return node def __call__(self, *args, **kwargs): self.__xml_update(args, kwargs) return self def __unicode__(self): return str(self).decode(self.__document()['encoding']) def __str__(self): return tostring(~self, self.__document()['encoding']) def __invert__(self): builder = self.__document()['builder']() self.__toxml(builder, 0) return builder.close() def __child_tag_count(self): return len([child for child in self.__childs if not isinstance(child, basestring)]) def __toxml(self, builder, level): if self.__document()['formatted']: tab = "\n" + self.__document()['tabstep'] * level builder.data(tab) else: tab = "" builder.start(self.__tag, self.__attrs) for child in self.__childs: if isinstance(child, basestring): builder.data(child) else: child.__toxml(builder, level + 1) if self.__child_tag_count() != 0 and tab: builder.data(tab) builder.end(self.__tag) def __lshift__(self, val): self.__xml_update([val], {}) return self def __enter__(self): return self.__document()(self) def __exit__(self, x, y, z): self.__document()(None) class XMLBuilder(object): def __init__(self, root_name, *args, **kwargs): root = XMLNode(weakref.ref(self), root_name, *args, **kwargs) self.__stack = [root] self.__opts = { 'formatted' : True, 'tabstep' : ' ' * 4, 'encoding' : 'utf-8', 'xml_header' : True, 'builder' : TreeBuilder } def __getitem__(self, name): return self.__opts[name] def __setitem__(self, name, val): self.__opts[name] = val def __getattr__(self, name): return getattr(self.__stack[-1], name) def __lshift__(self, val): return self.__stack[-1] << val def __call__(self, obj): if obj is None: self.__stack.pop() else: self.__stack.append(obj) return self def __str__(self): if self['xml_header']: hdr = '\n' % self['encoding'] else: hdr = "" return hdr + str(self.__stack[0]) def __invert__(self): return ~self.__stack[0] #------------------------------------------------------------------------------- def make_text_attr(text, attrs_dict): if attrs_dict.items(): attrs = ", ".join('{0}={1!r}'.format(name, val) for name, val in attrs_dict.items()) else: attrs = "" if text and text.strip() != '': text = text.strip() else: text = "" if text and attrs: text_attr = "{0!r}, {1}".format(text, attrs) elif text: text_attr = repr(text) else: text_attr = attrs return text_attr def xml2py(xml, name, tabstep=" " * 4): etree = fromstring(xml) text_attr = make_text_attr(etree.text, etree.attrib) if text_attr: res = "{0} = XMLBuilder({0!r}, {1})".format(name, text_attr) else: res = "{0} = XMLBuilder({1})".format(name) return res + "\n" + "\n".join( tabstep * tab + data for tab, data in _xml2py(etree, name)) def _xml2py(etree, name): childs = etree.getchildren() text_attr = make_text_attr(etree.text, etree.attrib) if len(childs) != 0: yield 0, "with {0}.{1}({2}):".format(name, etree.tag, text_attr) for elem in childs: for tab, data in _xml2py(elem, name): yield tab + 1, data else: yield 0, "{0}.{1}({2})".format(name, etree.tag, text_attr) #------------------------------------------------------------------------------- if __name__ == "__main__": import sys if len(sys.argv) != 2: sys.stderr.write("Usage : {0} XML_FILE_NAME\n".format(sys.argv[0])) else: print(xml2py(open(sys.argv[1]).read(), 'root')) #------------------------------------------------------------------------------- xmlbuilder-1.0/xmlbuilder/test.py0000664000175000017500000001233111671770746017475 0ustar koderkoder00000000000000# -*- encoding:utf8 -*- from __future__ import with_statement from nose.tools import eq_, raises from xmlbuilder import XMLBuilder class TestXMLBuilder(object): def setUp(self): self.xml = XMLBuilder('root') self.xml['xml_header'] = False self.xml['formatted'] = False def test_very_simple(self): eq_(str(self.xml), "") def test_xml_header(self): self.xml['xml_header'] = True eq_(str(self.xml), '\n') def test_unicode(self): self.xml.t eq_(unicode(self.xml), u"") def test_simple1(self): self.xml.t eq_(str(self.xml), "") def test_simple2(self): self.xml.t("some_data") eq_(str(self.xml), "some_data") def test_simple3(self): self.xml.t(a='1') eq_(str(self.xml), '') def test_simple4(self): self.xml.t("some data", a='1') eq_(str(self.xml), 'some data') def test_simple5(self): self.xml << "some data" eq_(str(self.xml), 'some data') def test_simple6(self): self.xml << "some data" << '111' << '222' eq_(str(self.xml), 'some data111222') @raises(ValueError) def test_wrong_data1(self): self.xml << 3 @raises(ValueError) def test_wrong_data2(self): self.xml.t(attr=3) @raises(ValueError) def test_wrong_data2(self): self.xml.t("some_data", attr=3) @raises(ValueError) def test_wrong_data2(self): self.xml.t(True, attr=3) @raises(ValueError) def test_wrong_data3(self): self.xml.t(3) test_formatter1_res = \ """ mmm """ def test_formatter1(self): self.xml['formatted'] = True self.xml.t1(m='1').t2 self.xml.t3('mmm') eq_(str(self.xml), self.test_formatter1_res) test_formatter2_res = '\n\t\n\t\t\n\t\n\tmmm\n' def test_formatter2(self): self.xml['formatted'] = True self.xml['tabstep'] = '\t' self.xml.t1(m='1').t2 self.xml.t3('mmm') eq_(str(self.xml), self.test_formatter2_res) def test_attrib(self): self.xml.t1(m='1').t2 self.xml.t3('mmm') eq_(str(self.xml), 'mmm') def test_with1(self): with self.xml.tree_root: pass eq_(str(self.xml), "") def test_with2(self): with self.xml.tree_root('rr'): pass eq_(str(self.xml), "rr") def test_with3(self): with self.xml.tree_root(a='dt'): pass eq_(str(self.xml), '') def test_with4(self): with self.xml.tree_root('mm', a='dt'): pass eq_(str(self.xml), 'mm') def test_with5(self): with self.xml.tree_root(a='dt'): self.xml << '11' eq_(str(self.xml), '11') def test_with6(self): with self.xml.tree_root(a='dt'): self.xml << '11' self.xml.tt eq_(str(self.xml), '11') def test_unicode(self): with self.xml.tree_root(a=u'dt'): self.xml << u'11' self.xml.tt('12') eq_(str(self.xml), u'1112') def test_unicode1(self): with self.xml.tree_root(a=u'dt'): self.xml << u'11' self.xml.tt('12') eq_(unicode(self.xml), u'1112') def test_unicode2(self): with self.xml.tree_root(a=u'dt'): self.xml << u'бла-бла-бла' self.xml.tt('12') eq_(str(self.xml).decode('utf8'), u'бла-бла-бла12') def test_with_all(self): self.xml.top with self.xml.tree_root('some data', attr='12'): self.xml.child1 self.xml.child2('child data', attr='11') with self.xml.tree_subroot(attr='13'): self.xml.very_child('very data') with self.xml.tree_subsubroot: pass eq_(str(self.xml), '' + '' + 'some data' + '' + 'child data' + '' + 'very data' '' + '' + '' + '') xmlbuilder-1.0/xmlbuilder.egg-info/0000775000175000017500000000000011671771754017636 5ustar koderkoder00000000000000xmlbuilder-1.0/xmlbuilder.egg-info/top_level.txt0000664000175000017500000000001311671771754022362 0ustar koderkoder00000000000000xmlbuilder xmlbuilder-1.0/xmlbuilder.egg-info/PKG-INFO0000664000175000017500000000502111671771754020731 0ustar koderkoder00000000000000Metadata-Version: 1.0 Name: xmlbuilder Version: 1.0 Summary: pythonic way to crate xml/(x)html files Home-page: UNKNOWN Author: Kostiantyn Danylov aka koder Author-email: koder.mail@gmail.com License: LGPL v3 Description: XMLBuilder is tiny library build on top of ElementTree.TreeBuilder to make xml files creation more pythonomic. `XMLBuilder` use `with` statement and attribute access to define xml document structure. Only 2.5+ python versions are supported. from __future__ import with_statement # only for python 2.5 from xmlbuilder import XMLBuilder x = XMLBuilder('root') x.some_tag x.some_tag_with_data('text', a='12') with x.some_tree(a='1'): with x.data: x.mmm for i in range(10): x.node(val=str(i)) etree_node = ~x # <= return xml.etree.ElementTree object print str(x) # <= string object will result: text There some fields, which allow xml output customization: formatted = produce formatted xml. default = True tabstep = tab string, used for formatting. default = ' ' * 4 encoding = xml document encoding. default = 'utf-8' xml_header = add xml header () to begining of the document. default = True builder = builder class, used for create dcument. Default = xml.etree.ElementTree.TreeBuilder Options can be readed by x = XMLBuilder('root') print x[option_name] and changed by x[option_name] = new_val Look at xmlbuilder/test.py for UT and more examples. Happy xml'ing. Platform: UNKNOWN xmlbuilder-1.0/xmlbuilder.egg-info/SOURCES.txt0000664000175000017500000000030511671771754021520 0ustar koderkoder00000000000000README.txt setup.py xmlbuilder/__init__.py xmlbuilder/test.py xmlbuilder.egg-info/PKG-INFO xmlbuilder.egg-info/SOURCES.txt xmlbuilder.egg-info/dependency_links.txt xmlbuilder.egg-info/top_level.txtxmlbuilder-1.0/xmlbuilder.egg-info/dependency_links.txt0000664000175000017500000000000111671771754023704 0ustar koderkoder00000000000000 xmlbuilder-1.0/setup.cfg0000664000175000017500000000007311671771754015616 0ustar koderkoder00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 xmlbuilder-1.0/PKG-INFO0000664000175000017500000000502111671771754015070 0ustar koderkoder00000000000000Metadata-Version: 1.0 Name: xmlbuilder Version: 1.0 Summary: pythonic way to crate xml/(x)html files Home-page: UNKNOWN Author: Kostiantyn Danylov aka koder Author-email: koder.mail@gmail.com License: LGPL v3 Description: XMLBuilder is tiny library build on top of ElementTree.TreeBuilder to make xml files creation more pythonomic. `XMLBuilder` use `with` statement and attribute access to define xml document structure. Only 2.5+ python versions are supported. from __future__ import with_statement # only for python 2.5 from xmlbuilder import XMLBuilder x = XMLBuilder('root') x.some_tag x.some_tag_with_data('text', a='12') with x.some_tree(a='1'): with x.data: x.mmm for i in range(10): x.node(val=str(i)) etree_node = ~x # <= return xml.etree.ElementTree object print str(x) # <= string object will result: text There some fields, which allow xml output customization: formatted = produce formatted xml. default = True tabstep = tab string, used for formatting. default = ' ' * 4 encoding = xml document encoding. default = 'utf-8' xml_header = add xml header () to begining of the document. default = True builder = builder class, used for create dcument. Default = xml.etree.ElementTree.TreeBuilder Options can be readed by x = XMLBuilder('root') print x[option_name] and changed by x[option_name] = new_val Look at xmlbuilder/test.py for UT and more examples. Happy xml'ing. Platform: UNKNOWN xmlbuilder-1.0/setup.py0000664000175000017500000000052411671771123015476 0ustar koderkoder00000000000000from setuptools import setup, find_packages setup( name='xmlbuilder', version='1.0', description="pythonic way to crate xml/(x)html files", author='Kostiantyn Danylov aka koder', author_email='koder.mail@gmail.com', packages=find_packages(), license='LGPL v3', long_description=open('README.txt').read(), ) xmlbuilder-1.0/README.txt0000664000175000017500000000343011671771107015463 0ustar koderkoder00000000000000XMLBuilder is tiny library build on top of ElementTree.TreeBuilder to make xml files creation more pythonomic. `XMLBuilder` use `with` statement and attribute access to define xml document structure. Only 2.5+ python versions are supported. from __future__ import with_statement # only for python 2.5 from xmlbuilder import XMLBuilder x = XMLBuilder('root') x.some_tag x.some_tag_with_data('text', a='12') with x.some_tree(a='1'): with x.data: x.mmm for i in range(10): x.node(val=str(i)) etree_node = ~x # <= return xml.etree.ElementTree object print str(x) # <= string object will result: text There some fields, which allow xml output customization: formatted = produce formatted xml. default = True tabstep = tab string, used for formatting. default = ' ' * 4 encoding = xml document encoding. default = 'utf-8' xml_header = add xml header () to begining of the document. default = True builder = builder class, used for create dcument. Default = xml.etree.ElementTree.TreeBuilder Options can be readed by x = XMLBuilder('root') print x[option_name] and changed by x[option_name] = new_val Look at xmlbuilder/test.py for UT and more examples. Happy xml'ing.