--- /dev/null
+The MIT License\r
+\r
+Copyright (c) 2008 Konstantin Danilov aka koder\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a copy\r
+of this software and associated documentation files (the "Software"), to deal\r
+in the Software without restriction, including without limitation the rights\r
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+copies of the Software, and to permit persons to whom the Software is\r
+furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice shall be included in\r
+all copies or substantial portions of the Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+THE SOFTWARE.\r
--- /dev/null
+include xmlbuild/docs *.rst\r
+include . LICENSE
\ No newline at end of file
--- /dev/null
+Metadata-Version: 1.0\r
+Name: xmlbuilder\r
+Version: 0.9\r
+Summary: Pythonic way to create xml files\r
+Home-page: http://pypi.python.org/pypi/xmlbuilder\r
+Author: koder\r
+Author-email: koder_dot_mail@gmail_dot_com\r
+License: MIT\r
+Download-URL: http://pypi.python.org/pypi/xmlbuilder\r
+Description: Example of usage:\r
+ -----------------\r
+ \r
+ \r
+ from __future__ import with_statement\r
+ from xmlbuilder import XMLBuilder\r
+ x = XMLBuilder(format=True)\r
+ with x.root(a = 1):\r
+ with x.data:\r
+ [x << ('node',{'val':i}) for i in range(10)]\r
+ \r
+ print str(x)\r
+ \r
+ will print\r
+ \r
+ <root a="1">\r
+ <data>\r
+ <node val="0" />\r
+ <node val="1" />\r
+ <node val="2" />\r
+ <node val="3" />\r
+ <node val="4" />\r
+ <node val="5" />\r
+ <node val="6" />\r
+ <node val="7" />\r
+ <node val="8" />\r
+ <node val="9" />\r
+ </data>\r
+ </root>\r
+ \r
+ Mercurial repo:http://hg.assembla.com/MyPackages/\r
+ \r
+ Documentations\r
+ --------------\r
+ `XMLBuilder` is simple library build on top of `ElementTree.TreeBuilder` to\r
+ simplify xml files creation as much as possible. Althow it can produce\r
+ structured result with identated child tags. `XMLBuilder` use python `with`\r
+ statement to define xml tag levels and `<<` operator for simple cases -\r
+ text and tag without childs.\r
+ \r
+ First we need to create xmlbuilder\r
+ \r
+ from xmlbuilder import XMLBuilder\r
+ # params - encoding = 'utf8',\r
+ # builder = None, - ElementTree.TreeBuilder\r
+ # tab_level = None, - current tab l;evel - for formatted output only\r
+ # format = False, - create formatted output\r
+ # tab_step = " " * 4 - indentation step\r
+ xml = XMLBuilder()\r
+ \r
+ \r
+ Use `with` statement to make document structure\r
+ #create and open tag 'root_tag' with text 'text' and attributes\r
+ with xml.root_tag(text,attr1=val1,attr2=val2):\r
+ #create and open tag 'sub_tag'\r
+ with xml.sub_tag(text,attr3=val3):\r
+ #create tag which are not valid python identificator\r
+ with xml('one-more-sub-tag',attr7=val37):\r
+ xml << "Some textual data"\r
+ #here tag 'one-more-sub-tag' are closed\r
+ #Tags without children can be created using `<<` operator\r
+ for val in range(15):\r
+ xml << ('message',"python rocks!"[:i])\r
+ #create 15 child tag like <message> python r</message>\r
+ #all tags closed\r
+ node = ~x # get etree.ElementTree object\r
+ xml_data = str(x)\r
+ unicode_xml_data = unicode(x)\r
+ \r
+Keywords: xml\r
+Platform: UNKNOWN\r
--- /dev/null
+Pythonic way to build xml files
\ No newline at end of file
--- /dev/null
+[egg_info]\r
+tag_build = \r
+tag_date = 0\r
+tag_svn_revision = 0\r
+\r
--- /dev/null
+#!/usr/bin/env python\r
+#-------------------------------------------------------------------------------\r
+import os\r
+import sys\r
+import glob\r
+import os.path\r
+from setuptools import setup\r
+#from distutils.core import setup\r
+#-------------------------------------------------------------------------------\r
+if 'upload' in sys.argv:\r
+ # for .pypirc file\r
+ try:\r
+ os.environ['HOME']\r
+ except KeyError:\r
+ os.environ['HOME'] = '..\\'\r
+#-------------------------------------------------------------------------------\r
+fpath = lambda x : os.path.join(*x.split('/'))\r
+#-------------------------------------------------------------------------------\r
+PYPI_URL = 'http://pypi.python.org/pypi/xmlbuilder'\r
+ld = open(fpath('xmlbuilder/docs/long_descr.rst')).read()\r
+ld = ld.replace('&','&').replace('<','<').replace('>','>')\r
+setup(\r
+ name = "xmlbuilder",\r
+ fullname = "xmlbuilder",\r
+ version = "0.9",\r
+ packages = ["xmlbuilder"],\r
+ package_dir = {'xmlbuilder':'xmlbuilder'},\r
+ author = "koder",\r
+ author_email = "koder_dot_mail@gmail_dot_com",\r
+ maintainer = 'koder',\r
+ maintainer_email = "koder_dot_mail@gmail_dot_com",\r
+ description = "Pythonic way to create xml files",\r
+ license = "MIT",\r
+ keywords = "xml",\r
+ test_suite = "xml_buider.tests",\r
+ url = PYPI_URL,\r
+ download_url = PYPI_URL,\r
+ long_description = ld,\r
+ #include_package_data = True,\r
+ #package_data = {'xmlbuilder':["docs/*.rst"]},\r
+ #data_files = [('', ['xmlbuilder/docs/long_descr.rst'])]\r
+)\r
+#-------------------------------------------------------------------------------\r
--- /dev/null
+Metadata-Version: 1.0\r
+Name: xmlbuilder\r
+Version: 0.9\r
+Summary: Pythonic way to create xml files\r
+Home-page: http://pypi.python.org/pypi/xmlbuilder\r
+Author: koder\r
+Author-email: koder_dot_mail@gmail_dot_com\r
+License: MIT\r
+Download-URL: http://pypi.python.org/pypi/xmlbuilder\r
+Description: Example of usage:\r
+ -----------------\r
+ \r
+ \r
+ from __future__ import with_statement\r
+ from xmlbuilder import XMLBuilder\r
+ x = XMLBuilder(format=True)\r
+ with x.root(a = 1):\r
+ with x.data:\r
+ [x << ('node',{'val':i}) for i in range(10)]\r
+ \r
+ print str(x)\r
+ \r
+ will print\r
+ \r
+ <root a="1">\r
+ <data>\r
+ <node val="0" />\r
+ <node val="1" />\r
+ <node val="2" />\r
+ <node val="3" />\r
+ <node val="4" />\r
+ <node val="5" />\r
+ <node val="6" />\r
+ <node val="7" />\r
+ <node val="8" />\r
+ <node val="9" />\r
+ </data>\r
+ </root>\r
+ \r
+ Mercurial repo:http://hg.assembla.com/MyPackages/\r
+ \r
+ Documentations\r
+ --------------\r
+ `XMLBuilder` is simple library build on top of `ElementTree.TreeBuilder` to\r
+ simplify xml files creation as much as possible. Althow it can produce\r
+ structured result with identated child tags. `XMLBuilder` use python `with`\r
+ statement to define xml tag levels and `<<` operator for simple cases -\r
+ text and tag without childs.\r
+ \r
+ First we need to create xmlbuilder\r
+ \r
+ from xmlbuilder import XMLBuilder\r
+ # params - encoding = 'utf8',\r
+ # builder = None, - ElementTree.TreeBuilder\r
+ # tab_level = None, - current tab l;evel - for formatted output only\r
+ # format = False, - create formatted output\r
+ # tab_step = " " * 4 - indentation step\r
+ xml = XMLBuilder()\r
+ \r
+ \r
+ Use `with` statement to make document structure\r
+ #create and open tag 'root_tag' with text 'text' and attributes\r
+ with xml.root_tag(text,attr1=val1,attr2=val2):\r
+ #create and open tag 'sub_tag'\r
+ with xml.sub_tag(text,attr3=val3):\r
+ #create tag which are not valid python identificator\r
+ with xml('one-more-sub-tag',attr7=val37):\r
+ xml << "Some textual data"\r
+ #here tag 'one-more-sub-tag' are closed\r
+ #Tags without children can be created using `<<` operator\r
+ for val in range(15):\r
+ xml << ('message',"python rocks!"[:i])\r
+ #create 15 child tag like <message> python r</message>\r
+ #all tags closed\r
+ node = ~x # get etree.ElementTree object\r
+ xml_data = str(x)\r
+ unicode_xml_data = unicode(x)\r
+ \r
+Keywords: xml\r
+Platform: UNKNOWN\r
--- /dev/null
+LICENSE
+MANIFEST.in
+README.txt
+setup.py
+xmlbuilder/__init__.py
+xmlbuilder.egg-info/PKG-INFO
+xmlbuilder.egg-info/SOURCES.txt
+xmlbuilder.egg-info/dependency_links.txt
+xmlbuilder.egg-info/top_level.txt
+xmlbuilder/docs/long_descr.rst
+xmlbuilder/tests/__init__.py
\ No newline at end of file
--- /dev/null
+xmlbuilder
--- /dev/null
+#!/usr/bin/env python\r
+#-------------------------------------------------------------------------------\r
+from __future__ import with_statement\r
+#-------------------------------------------------------------------------------\r
+from xml.etree.ElementTree import TreeBuilder,tostring\r
+#-------------------------------------------------------------------------------\r
+__all__ = ["XMLBuilder"]\r
+__doc__ = """\r
+XMLBuilder is simple library build on top of ElementTree.TreeBuilder to\r
+simplify xml files creation as much as possible. Althow it can produce\r
+structured result with identated child tags. `XMLBuilder` use python `with`\r
+statement to define xml tag levels and `<<` operator for simple cases -\r
+text and tag without childs.\r
+\r
+from __future__ import with_statement\r
+from xmlbuilder import XMLBuilder\r
+x = XMLBuilder(format=True)\r
+with x.root(a = 1):\r
+ with x.data:\r
+ [x << ('node',{'val':i}) for i in range(10)]\r
+\r
+etree_node = ~x\r
+print str(x)\r
+"""\r
+#-------------------------------------------------------------------------------\r
+class _XMLNode(object):\r
+ """Class for internal usage"""\r
+ def __init__(self,parent,name,builder):\r
+ self.builder = builder\r
+ self.name = name\r
+ self.text = []\r
+ self.attrs = {}\r
+ self.entered = False\r
+ self.parent = parent\r
+ def __call__(self,*dt,**mp):\r
+ text = "".join(dt)\r
+ if self.entered:\r
+ self.builder.data(text)\r
+ else:\r
+ self.text.append(text)\r
+ if self.entered:\r
+ raise ValueError("Can't add attributes to already opened element")\r
+ smp = dict((k,str(v)) for k,v in mp.items())\r
+ self.attrs.update(smp)\r
+ return self\r
+ def __enter__(self):\r
+ self.parent += 1\r
+ self.builder.start(self.name,self.attrs)\r
+ self.builder.data("".join(self.text))\r
+ self.entered = True\r
+ return self\r
+ def __exit__(self,x,y,z):\r
+ self.parent -= 1\r
+ self.builder.end(self.name)\r
+ return False\r
+#-------------------------------------------------------------------------------\r
+class XMLBuilder(object):\r
+ """XmlBuilder(encoding = 'utf-8', # result xml file encoding\r
+ builder = None, #etree.TreeBuilder or compatible class\r
+ tab_level = None, #current tabulation level - string\r
+ format = False, # make formatted output\r
+ tab_step = " " * 4) # tabulation step\r
+ use str(builder) or unicode(builder) to get xml text or\r
+ ~builder to obtaine etree.ElementTree\r
+ """\r
+ def __init__(self,encoding = 'utf-8',\r
+ builder = None,\r
+ tab_level = None,\r
+ format = False,\r
+ tab_step = " " * 4):\r
+ self.__builder = builder or TreeBuilder()\r
+ self.__encoding = encoding \r
+ if format :\r
+ if tab_level is None:\r
+ tab_level = ""\r
+ if tab_level is not None:\r
+ if not format:\r
+ raise ValueError("format is False, but tab_level not None")\r
+ self.__tab_level = tab_level # current format level\r
+ self.__tab_step = tab_step # format step\r
+ self.__has_sub_tag = False # True, if current tag had childrens\r
+ self.__node = None\r
+ # called from _XMLNode when tag opened\r
+ def __iadd__(self,val):\r
+ self.__has_sub_tag = False\r
+ if self.__tab_level is not None:\r
+ self.__builder.data("\n" + self.__tab_level)\r
+ self.__tab_level += self.__tab_step\r
+ return self\r
+ # called from XMLNode when tag closed\r
+ def __isub__(self,val):\r
+ if self.__tab_level is not None:\r
+ self.__tab_level = self.__tab_level[:-len(self.__tab_step)]\r
+ if self.__has_sub_tag:\r
+ self.__builder.data("\n" + self.__tab_level)\r
+ self.__has_sub_tag = True\r
+ return self\r
+ def __getattr__(self,name):\r
+ return _XMLNode(self,name,self.__builder)\r
+ def __call__(self,name,*dt,**mp):\r
+ x = _XMLNode(self,name,self.__builder)\r
+ x(*dt,**mp)\r
+ return x\r
+ #create new tag or add text\r
+ #possible shift values\r
+ #string - text\r
+ #tuple(string1,string2,dict) - new tag with name string1,attrs = dict,and text string2\r
+ #dict and string2 are optional\r
+ def __lshift__(self,val):\r
+ if isinstance(val,basestring):\r
+ self.__builder.data(val)\r
+ else:\r
+ self.__has_sub_tag = True\r
+ assert hasattr(val,'__len__'),\\r
+ 'Shifted value should be tuple or list like object not %r' % val\r
+ assert hasattr(val,'__getitem__'),\\r
+ 'Shifted value should be tuple or list like object not %r' % val\r
+ name = val[0]\r
+ if len(val) == 3:\r
+ text = val[1]\r
+ attrs = val[2]\r
+ elif len(val) == 1:\r
+ text = ""\r
+ attrs = {}\r
+ elif len(val) == 2:\r
+ if isinstance(val[1],basestring):\r
+ text = val[1]\r
+ attrs = {}\r
+ else:\r
+ text = ""\r
+ attrs = val[1]\r
+ if self.__tab_level is not None:\r
+ self.__builder.data("\n" + self.__tab_level)\r
+ self.__builder.start(name,\r
+ dict((k,str(v)) for k,v in attrs.items()))\r
+ if text:\r
+ self.__builder.data(text)\r
+ self.__builder.end(name)\r
+ return self # to allow xml << some1 << some2 << some3\r
+ #close builder\r
+ def __invert__(self):\r
+ if self.__node is not None:\r
+ return self.__node\r
+ self.__node = self.__builder.close()\r
+ return self.__node\r
+ def __str__(self):\r
+ """return generated xml"""\r
+ return tostring(~self,self.__encoding)\r
+ def __unicode__(self):\r
+ """return generated xml"""\r
+ res = tostring(~self,self.__encoding)\r
+ return res.decode(self.__encoding)\r
+#-------------------------------------------------------------------------------\r
--- /dev/null
+Example of usage:\r
+-----------------\r
+\r
+\r
+from __future__ import with_statement\r
+from xmlbuilder import XMLBuilder\r
+x = XMLBuilder(format=True)\r
+with x.root(a = 1):\r
+ with x.data:\r
+ [x << ('node',{'val':i}) for i in range(10)]\r
+\r
+print str(x)\r
+\r
+will print\r
+\r
+<root a="1">\r
+ <data>\r
+ <node val="0" />\r
+ <node val="1" />\r
+ <node val="2" />\r
+ <node val="3" />\r
+ <node val="4" />\r
+ <node val="5" />\r
+ <node val="6" />\r
+ <node val="7" />\r
+ <node val="8" />\r
+ <node val="9" />\r
+ </data>\r
+</root>\r
+\r
+Mercurial repo:http://hg.assembla.com/MyPackages/\r
+\r
+Documentations\r
+--------------\r
+`XMLBuilder` is simple library build on top of `ElementTree.TreeBuilder` to\r
+simplify xml files creation as much as possible. Althow it can produce\r
+structured result with identated child tags. `XMLBuilder` use python `with`\r
+statement to define xml tag levels and `<<` operator for simple cases -\r
+text and tag without childs.\r
+\r
+First we need to create xmlbuilder\r
+\r
+ from xmlbuilder import XMLBuilder\r
+ # params - encoding = 'utf8',\r
+ # builder = None, - ElementTree.TreeBuilder \r
+ # tab_level = None, - current tab l;evel - for formatted output only\r
+ # format = False, - create formatted output\r
+ # tab_step = " " * 4 - indentation step\r
+ xml = XMLBuilder()\r
+\r
+\r
+Use `with` statement to make document structure\r
+ #create and open tag 'root_tag' with text 'text' and attributes\r
+ with xml.root_tag(text,attr1=val1,attr2=val2):\r
+ #create and open tag 'sub_tag'\r
+ with xml.sub_tag(text,attr3=val3):\r
+ #create tag which are not valid python identificator\r
+ with xml('one-more-sub-tag',attr7=val37):\r
+ xml << "Some textual data"\r
+ #here tag 'one-more-sub-tag' are closed\r
+ #Tags without children can be created using `<<` operator\r
+ for val in range(15):\r
+ xml << ('message',"python rocks!"[:i])\r
+ #create 15 child tag like <message> python r</message>\r
+ #all tags closed\r
+ node = ~x # get etree.ElementTree object\r
+ xml_data = str(x)\r
+ unicode_xml_data = unicode(x)\r
--- /dev/null
+#!/usr/bin/env python\r
+from __future__ import with_statement\r
+#-------------------------------------------------------------------------------\r
+import unittest\r
+from xml.etree.ElementTree import fromstring\r
+#-------------------------------------------------------------------------------\r
+from xmlbuilder import XMLBuilder\r
+#-------------------------------------------------------------------------------\r
+def xmlStructureEqual(xml1,xml2):\r
+ tree1 = fromstring(xml1)\r
+ tree2 = fromstring(xml2)\r
+ return _xmlStructureEqual(tree1,tree2)\r
+#-------------------------------------------------------------------------------\r
+def _xmlStructureEqual(tree1,tree2):\r
+ if tree1.tag != tree2.tag:\r
+ return False\r
+ attr1 = list(tree1.attrib.items())\r
+ attr1.sort()\r
+ attr2 = list(tree2.attrib.items())\r
+ attr2.sort()\r
+ if attr1 != attr2:\r
+ return False\r
+ return tree1.getchildren() == tree2.getchildren()\r
+#-------------------------------------------------------------------------------\r
+result1 = \\r
+"""\r
+<root>\r
+ <array />\r
+ <array len="10">\r
+ <el val="0" />\r
+ <el val="1">xyz</el>\r
+ <el val="2">abc</el>\r
+ <el val="3" />\r
+ <el val="4" />\r
+ <el val="5" />\r
+ <sup-el val="23">test </sup-el>\r
+ </array>\r
+</root>\r
+""".strip()\r
+#-------------------------------------------------------------------------------\r
+class TestXMLBuilder(unittest.TestCase):\r
+ def testShift(self):\r
+ xml = (XMLBuilder() << ('root',))\r
+ self.assertEqual(str(xml),"<root />")\r
+ \r
+ xml = XMLBuilder()\r
+ xml << ('root',"some text")\r
+ self.assertEqual(str(xml),"<root>some text</root>")\r
+ \r
+ xml = XMLBuilder()\r
+ xml << ('root',{'x':1,'y':'2'})\r
+ self.assert_(xmlStructureEqual(str(xml),"<root x='1' y='2'>some text</root>"))\r
+ \r
+ xml = XMLBuilder()\r
+ xml << ('root',{'x':1,'y':'2'})\r
+ self.assert_(xmlStructureEqual(str(xml),"<root x='1' y='2'></root>"))\r
+\r
+ xml = XMLBuilder()\r
+ xml << ('root',{'x':1,'y':'2'})\r
+ self.assert_(not xmlStructureEqual(str(xml),"<root x='2' y='2'></root>"))\r
+\r
+ \r
+ xml = XMLBuilder()\r
+ xml << ('root',"gonduras.ua",{'x':1,'y':'2'})\r
+ self.assert_(xmlStructureEqual(str(xml),"<root x='1' y='2'>gonduras.ua</root>"))\r
+ \r
+ xml = XMLBuilder()\r
+ xml << ('root',"gonduras.ua",{'x':1,'y':'2'})\r
+ self.assert_(xmlStructureEqual(str(xml),"<root x='1' y='2'>gonduras.com</root>"))\r
+ #---------------------------------------------------------------------------\r
+ def testWith(self):\r
+ xml = XMLBuilder()\r
+ with xml.root(lenght = 12):\r
+ pass\r
+ self.assertEqual(str(xml),'<root lenght="12" />')\r
+ \r
+ xml = XMLBuilder()\r
+ with xml.root():\r
+ xml << "text1" << "text2" << ('some_node',)\r
+ self.assertEqual(str(xml),"<root>text1text2<some_node /></root>")\r
+ #---------------------------------------------------------------------------\r
+ def testFormat(self):\r
+ x = XMLBuilder('utf-8',format = True)\r
+ with x.root():\r
+ x << ('array',)\r
+ with x.array(len = 10):\r
+ with x.el(val = 0):\r
+ pass\r
+ with x.el('xyz',val = 1):\r
+ pass\r
+ x << ("el","abc",{'val':2}) << ('el',dict(val=3))\r
+ x << ('el',dict(val=4)) << ('el',dict(val='5'))\r
+ with x('sup-el',val = 23):\r
+ x << "test "\r
+ self.assertEqual(str(x),result1)\r
+#-------------------------------------------------------------------------------\r
+if __name__ == '__main__':\r
+ unittest.main()\r
+#-------------------------------------------------------------------------------\r