Reputation: 1377
My goal is to build an xml template with placeholders for variable attributes. for some reasons, the template would not take in new data into its placeholders.
Here's an example:
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
Output:
<personal reference="500.txt">
<others:sequence>
<feature:name="name" age="age" dob="dob"/>
</others:sequence>
</personal>
Ideal output:
<personal reference="500.txt">
<others:sequence>
<feature:name="Michael" age="10" dob="15/10/1900"/>
</others:sequence>
</personal>
Any ideas? Thanks.
Upvotes: 3
Views: 2075
Reputation: 24836
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.
Upvotes: 4
Reputation: 879411
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>
Upvotes: 3