3

我想生成这个xml 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)

如果我同时更改AB如下所示:

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>

这是有效的,但不是所需的输出。

4

1 回答 1

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>
于 2013-12-04T16:15:01.940 回答