Short answer is: You should be focusing, and dealing with, the data (i.e., python object) and not the raw XML
Basic story: XML is supposed to be a representation of some data, or data set. You don't have a lot of detail in your question about the type of data, what it represents, etc, etc -- so I'll give you some basic answers.
Python choices: BeautifulSoup, lxml and other python libraries (ElementTree, etc.), make dealing with XML more easy. They let me read in, or write out, XML data much more easily than if I'd tried to work directly with the XML in raw form.
In the middle of those 2 (input,output) activities, my python program is dealing with a nice python object or some kind of parse tree I can walk. You can read data in, create an object from that string, manipulate it and write out XML.
Other choice, Templates: OK -- maybe you like XML and just want to "template" it so you can populate it with the data.
You might be more comfortable with this, if you aren't really manipulating the data -- but just representing it for output. And, this is similar to the XML strings you are currently using -- so may be more familiar.
Use Cheetah, Jinja, or other template libraries to help. Make a template for the XML file, using that template language.
For example, you just read a list of books from a file or database table. You would pass this list of book objects to the template engine, with a template, and then tell it to write out your XML output.
Example template for these book objects:
<?xml version="1.0"?>
<catalog>
{% for object in object_list %}
<book id="{{ object.bookID }}">
<author>{{ object.author_name }}</author>
<title>{{ object.title }}</title>
<genre>{{ object.genre }}</genre>
<price>{{ object.price }}</price>
<publish_date>{{ object.pub_date }}</publish_date>
<description>{{ object.description }}</description>
</book>
{% endfor %}
</catalog>
The template engine would loop through the "object_list" and output a long XML file with all your books. That would be much better than storing raw XML strings, as you currently are.
This makes the update & modification of the display of XML separate from the data, data storage, and data manipulation -- making your life easier.
Answer from joej on Stack OverflowShort answer is: You should be focusing, and dealing with, the data (i.e., python object) and not the raw XML
Basic story: XML is supposed to be a representation of some data, or data set. You don't have a lot of detail in your question about the type of data, what it represents, etc, etc -- so I'll give you some basic answers.
Python choices: BeautifulSoup, lxml and other python libraries (ElementTree, etc.), make dealing with XML more easy. They let me read in, or write out, XML data much more easily than if I'd tried to work directly with the XML in raw form.
In the middle of those 2 (input,output) activities, my python program is dealing with a nice python object or some kind of parse tree I can walk. You can read data in, create an object from that string, manipulate it and write out XML.
Other choice, Templates: OK -- maybe you like XML and just want to "template" it so you can populate it with the data.
You might be more comfortable with this, if you aren't really manipulating the data -- but just representing it for output. And, this is similar to the XML strings you are currently using -- so may be more familiar.
Use Cheetah, Jinja, or other template libraries to help. Make a template for the XML file, using that template language.
For example, you just read a list of books from a file or database table. You would pass this list of book objects to the template engine, with a template, and then tell it to write out your XML output.
Example template for these book objects:
<?xml version="1.0"?>
<catalog>
{% for object in object_list %}
<book id="{{ object.bookID }}">
<author>{{ object.author_name }}</author>
<title>{{ object.title }}</title>
<genre>{{ object.genre }}</genre>
<price>{{ object.price }}</price>
<publish_date>{{ object.pub_date }}</publish_date>
<description>{{ object.description }}</description>
</book>
{% endfor %}
</catalog>
The template engine would loop through the "object_list" and output a long XML file with all your books. That would be much better than storing raw XML strings, as you currently are.
This makes the update & modification of the display of XML separate from the data, data storage, and data manipulation -- making your life easier.
Two choices.
A template tool, for example Jinja2.
Build the DOM object. Not as bad as it sounds. ElementTree has a pleasant factory for building XML tags and creating the necessary structure.
Videos
I think the consideration should probably be about how the templates are going to be written. The point of templates is to make sure that people are no longer hand coding (html, LaTeX, xml, whatever). This is why templating engines allow inheritance and other fancy features.
So, Daniel Roseman has a good point when he says that getting humans to write XML is evil. To some extent, you're using templates so you don't have to do that.
With that in mind, the largest difference I've seen between python templating engines is not, in fact, whether they use XML or some custom syntax. The large difference seems to be whether or not the templating engines allow arbitrary python code to be embedded into the template.
You mentioned both Cheetah and Jinja2. Both have special syntax but Cheeta allows pretty much arbitrary python to be embeded in the template, while Jinja2 places heavy restrictions on what can be done with the template. Now you're looking at a trade off between potentially mixing business and presentation logic, with making your template clear and concise.
In the end, the benefits are going to come from how easy it is to read, write, re-read, and re-write your code.
The one overriding principle: getting humans to write XML is evil.
To create an XML document in Python, it seems easier to use the Yattag library.
from yattag import Doc
doc, tag, text = Doc().tagtext()
x = 2*5
with tag('personal', reference = "500.txt"):
with tag('others:sequence'):
doc.stag('feature', name = "Michael", age = str(x), dob = "15/10/1900")
print(doc.getvalue())
When run, the above code will generate the following XML:
<personal reference="500.txt">
<others:sequence>
<feature name="Michael" age="10" dob="15/10/1900" />
</others:sequence>
</personal>
Note: Indentation was added to the example above for readability, as getvalue returns a single line without spaces between tags. To produce a formatted document, use the indent function.
Your template needs curly braces:
x=2*5
xmlTemplate="""
<personal reference="500.txt">
<others:sequence>
<feature:name="{name}" age="{age}" dob="{dob}"/>
</others:sequence>
</personal>""".format(name='Michael', age=x, dob='15/10/1900')
print xmlTemplate
yields
<personal reference="500.txt">
<others:sequence>
<feature:name="Michael" age="10" dob="15/10/1900"/>
</others:sequence>
</personal>
The format method replaces names in curly-braces. Compare, for example,
In [20]: 'cheese'.format(cheese='Roquefort')
Out[20]: 'cheese'
In [21]: '{cheese}'.format(cheese='Roquefort')
Out[21]: 'Roquefort'
I see you have lxml. Excellent. In that case, you could use lxml.builder to construct XML. This will help you create valid XML:
import lxml.etree as ET
import lxml.builder as builder
E = builder.E
F = builder.ElementMaker(namespace='http://foo', nsmap={'others':'http://foo'})
x = 2*5
xmlTemplate = ET.tostring(F.root(
E.personal(
F.sequence(
E.feature(name='Michael',
age=str(x),
dob='15/10/1900')
), reference="500.txt")),
pretty_print=True)
print(xmlTemplate)
yields
<others:root xmlns:other="http://foo">
<personal reference="500.txt">
<others:sequence>
<feature dob="15/10/1900" age="10" name="Michael"/>
</others:sequence>
</personal>
</others:root>
and this string can be parsed by lxml using:
doc = ET.fromstring(xmlTemplate)
print(doc)
# <Element {http://foo}root at 0xb741866c>