Python:ElementTree,获取Element的命名空间字符串

问题描述 投票:0回答:9
python elementtree
9个回答
33
投票

对于正则表达式来说,这是一个完美的任务。

import re

def namespace(element):
    m = re.match(r'\{.*\}', element.tag)
    return m.group(0) if m else ''

30
投票

命名空间应位于“实际”标签之前的

Element.tag
中:

>>> root = tree.getroot()
>>> root.tag
'{http://maven.apache.org/POM/4.0.0}project'

要了解有关命名空间的更多信息,请查看 ElementTree:使用命名空间和限定名称


12
投票

我不确定这是否可以用

xml.etree
实现,但这里是你如何用
lxml.etree
做到这一点:

>>> from lxml import etree
>>> tree = etree.parse('example.xml')
>>> tree.xpath('namespace-uri(.)')
'http://maven.apache.org/POM/4.0.0'

11
投票

不使用正则表达式:

>>> root
<Element '{http://www.google.com/schemas/sitemap/0.84}urlset' at 0x2f7cc10>

>>> root.tag.split('}')[0].strip('{')
'http://www.google.com/schemas/sitemap/0.84'

2
投票

lxml.xtree
库的元素有一个名为
nsmap
的字典,它显示了当前标签范围内使用的所有命名空间。

>>> item = tree.getroot().iter().next()
>>> item.nsmap
{'md': 'urn:oasis:names:tc:SAML:2.0:metadata'}

2
投票

简短的回答是:

ElementTree._namspace_map[ElementTree._namspace_map.values().index('')]

但前提是您一直在打电话

ElementTree.register_namespace(prefix,uri)

响应迭代 结果时收到的每个 event=="start-ns"

ET.iterparse(...) 

并且您注册了 “start-ns”

回答“默认命名空间是什么?”这个问题,需要澄清两点:

(1) XML 规范规定,默认命名空间不一定在整个树中是全局的,而是可以在根下的任何元素处重新声明默认命名空间,并向下继承,直到遇到另一个默认命名空间重新声明。

(2) ElementTree 模块(事实上)可以处理没有根默认命名空间的类 XML 文档,前提是它们在文档中的任何位置都没有使用命名空间。 (* 条件可能不太严格,例如,是“if”,不一定是“iff”)。

也许还值得考虑“你想要它做什么?”请考虑 XML 文件在语义上可能是等效的,但在语法上却截然不同。例如,以下三个文件在语义上是等效的,但 A.xml 有一个默认名称空间声明,B.xml 有 3 个,而 C.xml 没有。

A.xml:
<a xlmns="http://A" xlmns:nsB0="http://B0" xlmns:nsB1="http://B1">
     <nsB0:b/>
     <nsB1:b/>
</a>

B.xml:
<a xlmns="http://A">
     <b xlmns="http://B0"/>
     <b xlmns="http://B1"/>
</a>

C.xml:
<{http://A}a>
     <{http://B0}b/>
     <{http://B1}b/>
</a>

文件 C.xml 是提供给 ElementTree 搜索功能的规范扩展语法表示。

如果您事先确定不会出现命名空间冲突,则可以在解析时修改元素标签,如下所述:Python ElementTree 模块:如何在使用“find”方法时忽略 XML 文件的命名空间来定位匹配元素”、“找到所有”


1
投票

我觉得看一下属性会更容易:

>>> root.attrib
{'{http://www.w3.org/2001/XMLSchema-instance}schemaLocation':
   'http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'}

-1
投票

结合上面的一些答案,我认为最短的代码是

theroot = tree.getroot()
theroot.attrib[theroot.keys()[0]]

-1
投票

这是我在 ElementTree 3.9+ 上的解决方案,

def get_element_namespaces(filename, element):
    namespace = []
    for key, value in ET.iterparse(filename, events=['start', 'start-ns']):
        print(key, value)
        if key == 'start-ns':
            namespace.append(value)
        else:
            if ET.tostring(element) == ET.tostring(value):
                return namespace
            namespace = []
    return namespaces

这将返回一个 [prefix:URL] 元组数组,如下所示:

[('android', 'http://schemas.android.com/apk/res/android'), ('tools', 'http://schemas.android.com/tools')]
© www.soinside.com 2019 - 2024. All rights reserved.