Python:在lxml中添加名称空间

Jas*_*oon 7 python lxml xml-namespaces

我正在尝试使用类似于此示例的lxml指定命名空间(取自此处):

<TreeInventory xsi:noNamespaceSchemaLocation="Trees.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</TreeInventory>
Run Code Online (Sandbox Code Playgroud)

我不确定如何添加要使用的Schema实例以及Schema位置.该文件让我开始,这样做是这样的:

>>> NS = 'http://www.w3.org/2001/XMLSchema-instance'
>>> TREE = '{%s}' % NS
>>> NSMAP = {None: NS}
>>> tree = etree.Element(TREE + 'TreeInventory', nsmap=NSMAP)
>>> etree.tostring(tree, pretty_print=True)
'<TreeInventory xmlns="http://www.w3.org/2001/XMLSchema-instance"/>\n'
Run Code Online (Sandbox Code Playgroud)

我不知道如何指定它是一个实例,然后还指定一个位置.看来这可以用nsmap关键字-arg 来完成etree.Element,但我不知道怎么做.

小智 9

在更多步骤中,为清楚起见:

>>> NS = 'http://www.w3.org/2001/XMLSchema-instance'
Run Code Online (Sandbox Code Playgroud)

据我所知,它是noNameSpaceSchemaLocation你想要命名空间的属性,而不是TreeInventory元素.所以:

>>> location_attribute = '{%s}noNameSpaceSchemaLocation' % NS
>>> elem = etree.Element('TreeInventory', attrib={location_attribute: 'Trees.xsd'})
>>> etree.tostring(elem, pretty_print=True)
'<TreeInventory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Trees.xsd"/>\n'
Run Code Online (Sandbox Code Playgroud)

这看起来像你想要的......你当然也可以先创建元素,不带属性,然后设置属性,如下所示:

>>> elem = etree.Element('TreeInventory')
>>> elem.set(location_attribute, 'Trees.xsd')
Run Code Online (Sandbox Code Playgroud)

至于nsmap参数:我相信它仅用于定义序列化时使用的前缀.在这种情况下,不需要它,因为lxml知道所讨论的命名空间的常用前缀是"xsi".如果它不是一个众所周知的命名空间,你可能会看到像"ns0","ns1"等前缀...,除非你指定了你喜欢的前缀.(记住:前缀不应该重要)

  • f 字符串 **do** 工作: `f'{{{NS}}}noNamespaceSchemaLocation'` (2认同)