在python lxml中设置和访问命名空间

时间:2018-01-05 13:41:21

标签: python namespaces lxml

我正在编写一个脚本,用python3和rdf:skos处理lxml文件:

我了解到我需要将XML提到的命名空间传递给findall过程。 (好吧,很奇怪,因为XML文件在标题中列出了这些,所以这似乎是一个不必要的步骤,但无论如何)。

致电

for concept in root.findall('.//skos:Concept', namespaces=root.nsmap):

有效,因为root.nsmap是由lxml构造的。

但后来在我的代码中我还需要对xml:lang

进行测试
for pl in concept.findall(".//skos:prefLabel[@xml:lang='en']", namespaces=root.nsmap):

这里python告诉我

SyntaxError: prefix 'xml' not found in prefix map

好的,是的,在我的skos文件中没有xml命名空间的额外声明。所以我尝试将它添加到root.nsmap dict

root.nsmap['xml'] = "http://www.w3.org/XML/1998/namespace"

但这也不起作用

nsmap = {'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'uneskos': 'http://purl.org/umu/uneskos#', 'iso-thes': 'http://purl.org/iso25964/skos-thes#', 'dcterms': 'http://purl.org/dc/terms/', 'skos': 'http://www.w3.org/2004/02/skos/core#', 'rdfs': 'http://www.w3.org/2000/01/rdf-schema#'}

似乎我不允许修改root.nsmap

有人知道这是怎么做到的吗?我过去使用Perl XML :: Twig处理了大量的XML,这非常非常舒服,而且我认为,Python社区(至少)有类似的方法可以做到这一点......但是如何?

任何提示都表示赞赏。

1 个答案:

答案 0 :(得分:0)

修改root.nsmap无效。但是你可以创建另一个字典并修改它。例如:

from lxml import etree

doc = """
<root xmlns:skos="http://www.w3.org/2004/02/skos/core#">
   <skos:prefLabel xml:lang='en'>FOO</skos:prefLabel>
   <skos:prefLabel xml:lang='de'>BAR</skos:prefLabel>
</root>"""

root = etree.fromstring(doc)
nsmap = root.nsmap
nsmap["xml"] = "http://www.w3.org/XML/1998/namespace" 

en = root.find(".//skos:prefLabel[@xml:lang='en']", namespaces=nsmap)
print(en.text)

输出:

FOO