通过'ElementTree'在Python中用命名空间解析XML
我有我想用Python的ElementTree
解析的以下XML:
<rdf:RDF xml:base="http://dbpedia.org/ontology/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns="http://dbpedia.org/ontology/">
<owl:Class rdf:about="http://dbpedia.org/ontology/BasketballLeague">
<rdfs:label xml:lang="en">basketball league</rdfs:label>
<rdfs:comment xml:lang="en">
a group of sports teams that compete against each other
in Basketball
</rdfs:comment>
</owl:Class>
</rdf:RDF>
我想查找所有owl:Class
标签,然后提取其中所有rdfs:label
实例的值。 我正在使用下面的代码:
tree = ET.parse("filename")
root = tree.getroot()
root.findall('owl:Class')
由于命名空间,我收到以下错误。
SyntaxError: prefix 'owl' not found in prefix map
我尝试阅读http://effbot.org/zone/element-namespaces.htm处的文档,但是由于上面的XML有多个嵌套命名空间,所以我仍然无法实现这个功能。
请让我知道如何更改代码来查找所有owl:Class
标签。
ElementTree对命名空间不太聪明。 你需要给.find()
, findall()
和iterfind()
方法一个明确的命名空间字典。 这没有很好记录:
namespaces = {'owl': 'http://www.w3.org/2002/07/owl#'} # add more as needed
root.findall('owl:Class', namespaces)
前缀只能在您传入的namespaces
参数中查找。这意味着您可以使用任何您喜欢的名称空间前缀; 该API将拆分owl:
part,在namespaces
字典中查找相应的名称空间URL,然后更改搜索以查找XPath表达式{http://www.w3.org/2002/07/owl}Class
。 当然你也可以使用相同的语法:
root.findall('{http://www.w3.org/2002/07/owl#}Class')
如果你可以切换到lxml
库,事情会更好; 该库支持相同的ElementTree API,但在元素上的.nsmap
属性中为您收集名称空间。
以下是如何使用lxml完成此操作,而不必对命名空间进行硬编码或为它们扫描文本(如Martijn Pieters所述):
from lxml import etree
tree = etree.parse("filename")
root = tree.getroot()
root.findall('owl:Class', root.nsmap)
注意 :这是一个对Python的ElementTree标准库非常有用的解决方案,不需要使用硬编码的名称空间。
要从XML数据中提取名称空间的前缀和URI,可以使用ElementTree.iterparse
函数,仅解析名称空间启动事件(start-ns):
>>> from io import StringIO
>>> from xml.etree import ElementTree
>>> my_schema = u'''<rdf:RDF xml:base="http://dbpedia.org/ontology/"
... xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
... xmlns:owl="http://www.w3.org/2002/07/owl#"
... xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
... xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
... xmlns="http://dbpedia.org/ontology/">
...
... <owl:Class rdf:about="http://dbpedia.org/ontology/BasketballLeague">
... <rdfs:label xml:lang="en">basketball league</rdfs:label>
... <rdfs:comment xml:lang="en">
... a group of sports teams that compete against each other
... in Basketball
... </rdfs:comment>
... </owl:Class>
...
... </rdf:RDF>'''
>>> my_namespaces = dict([
... node for _, node in ElementTree.iterparse(
... StringIO(my_schema), events=['start-ns']
... )
... ])
>>> from pprint import pprint
>>> pprint(my_namespaces)
{'': 'http://dbpedia.org/ontology/',
'owl': 'http://www.w3.org/2002/07/owl#',
'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'rdfs': 'http://www.w3.org/2000/01/rdf-schema#',
'xsd': 'http://www.w3.org/2001/XMLSchema#'}
然后字典可以作为参数传递给搜索函数:
root.findall('owl:Class', my_namespaces)
链接地址: http://www.djcxy.com/p/58793.html