如何从零构建具有可变属性的XML模板
我的目标是创建一个xml模板,这个模板里有一些占位符,用来放不同的属性值。但是出于某些原因,这个模板无法把新数据放进这些占位符里。
这里有个例子:
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
输出结果:
<personal reference="500.txt">
<others:sequence>
<feature:name="name" age="age" dob="dob"/>
</others:sequence>
</personal>
理想的输出结果:
<personal reference="500.txt">
<others:sequence>
<feature:name="Michael" age="10" dob="15/10/1900"/>
</others:sequence>
</personal>
有什么想法吗?谢谢。
2 个回答
4
在Python中创建XML文档,使用Yattag库似乎更简单。
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())
运行上面的代码后,会生成以下XML:
<personal reference="500.txt">
<others:sequence>
<feature name="Michael" age="10" dob="15/10/1900" />
</others:sequence>
</personal>
注意:为了让例子更易读,上面的代码添加了缩进,因为getvalue
返回的是一行,没有标签之间的空格。如果想要生成格式化的文档,可以使用indent
函数。
3
你的模板需要用大括号:
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
会得到
<personal reference="500.txt">
<others:sequence>
<feature:name="Michael" age="10" dob="15/10/1900"/>
</others:sequence>
</personal>
格式化方法会把大括号里的名字替换掉。比如说,看看这个:
In [20]: 'cheese'.format(cheese='Roquefort')
Out[20]: 'cheese'
In [21]: '{cheese}'.format(cheese='Roquefort')
Out[21]: 'Roquefort'
我看到你有 lxml
。太好了。在这种情况下,你可以使用 lxml.builder
来构建 XML。这样可以帮助你创建有效的 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)
会得到
<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>
而这个字符串可以用 lxml 解析,方法是:
doc = ET.fromstring(xmlTemplate)
print(doc)
# <Element {http://foo}root at 0xb741866c>