Python 更紧凑的ElementTree或lxml名称空间

Python 更紧凑的ElementTree或lxml名称空间,python,xml,lxml,elementtree,Python,Xml,Lxml,Elementtree,当子元素作为父元素位于不同的命名空间中时,我试图在ElementTree或lxml中获得命名空间的紧凑表示。以下是一个基本示例: from lxml import etree country = etree.Element("country") name = etree.SubElement(country, "{urn:test}name") name.text = "Canada" population = etree.SubElement(country, "{urn:test}pop

当子元素作为父元素位于不同的命名空间中时,我试图在ElementTree或lxml中获得命名空间的紧凑表示。以下是一个基本示例:

from lxml import etree

country = etree.Element("country")

name = etree.SubElement(country, "{urn:test}name")
name.text = "Canada"
population = etree.SubElement(country, "{urn:test}population")
population.text = "34M"
etree.register_namespace('tst', 'urn:test')

print( etree.tostring(country, pretty_print=True) )
我也尝试过这种方法:

ns = {"test" : "urn:test"}

country = etree.Element("country", nsmap=ns)

name = etree.SubElement(country, "{test}name")
name.text = "Canada"
population = etree.SubElement(country, "{test}population")
population.text = "34M"

print( etree.tostring(country, pretty_print=True) )
在这两种情况下,我都得到了如下结果:

<country>
    <ns0:name xmlns:ns0="urn:test">Canada</ns0:name>
    <ns1:population xmlns:ns1="urn:test">34M</ns1:population>
</country>
然后我得到以下输出:

<ns0:country xmlns:ns0="urn:test">
    <ns0:name>Canada</ns0:name>
    <ns0:population>34M</ns0:population>
</ns0:country>

加拿大
34米
但我真正想要的是:

<country xmlns:ns0="urn:test">
    <ns0:name>Canada</ns0:name>
    <ns0:population>34M</ns0:population>
<country>

加拿大
34米
有什么想法吗?

此代码:

从lxml导入etree
ns={“ns0”:“urn:test”}
country=etree.Element(“国家”,nsmap=ns)
name=etree.SubElement(国家,{urn:test}name”)
name.text=“加拿大”
population=etree.SubElement(国家,{urn:test}population”)
population.text=“34M”
打印(etree.tostring(国家,pretty\u print=True))
似乎提供了所需的输出:


加拿大
34米
但是您仍然需要自己维护
nsmap

from xml.etree import cElementTree as ET
##ET.register_namespace('tst', 'urn:test')
country = ET.Element("country")
name = ET.SubElement(country, "{urn:test}name")
name.text = "Canada"
population = ET.SubElement(country, "{urn:test}population")
population.text = "34M"
print prettify(country)
上面将给出(不注册任何名称空间):


加拿大
34米
并且,当我删除注释部分时,它将给出:

<?xml version="1.0" ?>
<country xmlns:tst="urn:test">
  <tst:name>Canada</tst:name>
  <tst:population>34M</tst:population>
</country>

加拿大
34米
注意:
美化
功能不可用

  • 元素的全名包含
    {namespace url}elementName
    ,而不是
    {prefix}elementName

    >>> from lxml import etree as ET
    >>> r = ET.Element('root', nsmap={'tst': 'urn:test'})
    >>> ET.SubElement(r, "{urn:test}child")
    <Element {urn:test}child at 0x2592a80>
    >>> ET.tostring(r)
    '<root xmlns:tst="urn:test"><tst:child/></root>'
    
  • <?xml version="1.0" ?>
    <country xmlns:tst="urn:test">
      <tst:name>Canada</tst:name>
      <tst:population>34M</tst:population>
    </country>
    
    >>> from lxml import etree as ET
    >>> r = ET.Element('root', nsmap={'tst': 'urn:test'})
    >>> ET.SubElement(r, "{urn:test}child")
    <Element {urn:test}child at 0x2592a80>
    >>> ET.tostring(r)
    '<root xmlns:tst="urn:test"><tst:child/></root>'
    
    >>> r = ET.Element('{urn:test}root', nsmap={None: 'urn:test'})
    >>> ET.SubElement(r, "{urn:test}child")
    <Element {urn:test}child at 0x2592b20>
    >>> ET.SubElement(r, "{urn:test}child")
    <Element {urn:test}child at 0x25928f0>
    >>> ET.tostring(r)
    '<root xmlns="urn:test"><child/><child/></root>'