我想用lxml
:
<aroot xmlns="http://a/">
<broot xmlns="http://b/" xmlns:a="http://a/">
<child1/>
<child2/>
<a:smalltag1/>
<a:smalltag2/>
</broot>
</aroot>
但是下面的代码(对于这个输出似乎是正确的),不会生成上面的xml。
from lxml import etree
from lxml.builder import ElementMaker
NS_A = 'http://a/'
NS_B = 'http://b/'
A = ElementMaker(namespace=NS_A, nsmap={None: NS_A, 'b': NS_B})
B = ElementMaker(namespace=NS_B, nsmap={None: NS_B, 'a': NS_A})
elem = A.aroot(
B.broot(
B.child1,
B.child2,
A.smalltag1,
A.smalltag2,
),
)
print(etree.tostring(elem, pretty_print=True).decode('ascii'))
这会产生:
<aroot xmlns:b="http://b/" xmlns="http://a/">
<b:broot>
<b:child1/>
<b:child2/>
<smalltag1/>
<smalltag1/>
</b:broot>
</aroot>
这是一个有效的xml,但我无法更改subelemnt broot
上的默认命名空间。
如果我按以下方式更改A
ElementMaker
:
A = ElementMaker(namespace=NS_A, nsmap={None: NS_A})
输出变为:
<aroot xmlns="http://a/">
<broot xmlns="http://b/">
<child1/>
<child2/>
<smalltag1/>
<smalltag2/>
</broot>
</aroot>
这是一个无效的xml(smalltag1
的命名空间现在是b)
如果我按如下方式更改A
和B
:
A = ElementMaker(namespace=NS_A, nsmap={None: NS_A})
B = ElementMaker(namespace=NS_B, nsmap={None: NS_B})
输出是:
<aroot xmlns="http://a/">
<broot xmlns="http://b/">
<child1/>
<child2/>
<smalltag1 xmlns="http://a/"/>
<smalltag2 xmlns="http://a/"/>
</broot>
</aroot>
哪个是有效的,但不是理想的输出。
答案 0 :(得分:3)
使用etree:
from lxml import etree
NS_A = 'http://a/'
NS_B = 'http://b/'
aroot = Element('{%s}aroot' % (NS_A), nsmap={None: NS_A})
broot = etree.SubElement(aroot, '{%s}broot' % (NS_B), nsmap={None: NS_B, 'a': NS_A})
etree.SubElement(broot, '{%s}child1' % (NS_B))
etree.SubElement(broot, '{%s}child2' % (NS_B))
etree.SubElement(broot, '{%s}smalltag1' % (NS_A))
etree.SubElement(broot, '{%s}smalltag2' % (NS_A))
print etree.tostring(aroot, pretty_print=True)
你得到:
<aroot xmlns="http://a/">
<broot xmlns:a="http://a/" xmlns="http://b/">
<child1/>
<child2/>
<a:smalltag1/>
<a:smalltag2/>
</broot>
</aroot>