xmlbuilder-1.0/ 0000775 0001750 0001750 00000000000 11671771754 013775 5 ustar koder koder 0000000 0000000 xmlbuilder-1.0/xmlbuilder/ 0000775 0001750 0001750 00000000000 11671771754 016144 5 ustar koder koder 0000000 0000000 xmlbuilder-1.0/xmlbuilder/__init__.py 0000664 0001750 0001750 00000017201 11671770676 020260 0 ustar koder koder 0000000 0000000 #!/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.py 0000664 0001750 0001750 00000012331 11671770746 017475 0 ustar koder koder 0000000 0000000 # -*- 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/ 0000775 0001750 0001750 00000000000 11671771754 017636 5 ustar koder koder 0000000 0000000 xmlbuilder-1.0/xmlbuilder.egg-info/top_level.txt 0000664 0001750 0001750 00000000013 11671771754 022362 0 ustar koder koder 0000000 0000000 xmlbuilder
xmlbuilder-1.0/xmlbuilder.egg-info/PKG-INFO 0000664 0001750 0001750 00000005021 11671771754 020731 0 ustar koder koder 0000000 0000000 Metadata-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.txt 0000664 0001750 0001750 00000000305 11671771754 021520 0 ustar koder koder 0000000 0000000 README.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.txt xmlbuilder-1.0/xmlbuilder.egg-info/dependency_links.txt 0000664 0001750 0001750 00000000001 11671771754 023704 0 ustar koder koder 0000000 0000000
xmlbuilder-1.0/setup.cfg 0000664 0001750 0001750 00000000073 11671771754 015616 0 ustar koder koder 0000000 0000000 [egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
xmlbuilder-1.0/PKG-INFO 0000664 0001750 0001750 00000005021 11671771754 015070 0 ustar koder koder 0000000 0000000 Metadata-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.py 0000664 0001750 0001750 00000000524 11671771123 015476 0 ustar koder koder 0000000 0000000 from 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.txt 0000664 0001750 0001750 00000003430 11671771107 015463 0 ustar koder koder 0000000 0000000 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.