0

我有一个地理数据文件

<gmd:MD_Metadata
xmlns:gmd="http://www.isotc211.org/2005/gmd"
xmlns:gco="http://www.isotc211.org/2005/gco" >
  <gmd:fileIdentifier>
    <gco:CharacterString>2ce585df-df23-45f6-b8e1-184e64e7e3b5</gco:CharacterString>
  </gmd:fileIdentifier>
  <gmd:language>
    <gmd:LanguageCode codeList="https://www.loc.gov/standards/iso639-2/" codeListValue="ger">ger</gmd:LanguageCode>
  </gmd:language>
</gmd:MD_Metadata>

利用 lxml.objectivy 我可以轻松解析它

from lxml import objectify
data = objectify.parse('rec.xml').getroot()

在数据中,“语言”公开为

(Pdb) data.language.LanguageCode
'ger'

但不是“文件标识符”

(Pdb) data.fileIdentifier.CharacterString
*** AttributeError: no such child: {http://www.isotc211.org/2005/gmd}CharacterString

显然,lxml 正在为“CharacterString”寻找错误的命名空间。

但是信息在那里

(Pdb) data.fileIdentifier['{http://www.isotc211.org/2005/gco}CharacterString']
'2ce585df-df23-45f6-b8e1-184e64e7e3b5'

如何说服 lxml 使用正确的命名空间?任何帮助表示赞赏

沃尔克

4

1 回答 1

1

这是意料之中的,也是 lxml.objectify 的工作原理。由于 {http://www.isotc211.org/2005/gco}CharacterString 来自另一个命名空间,而不是其父元素 ({"http://www.isotc211.org/2005/gmd}fileIdentifier),因此无法从具有“简单(点)属性查找”的父级。

相反,您必须使用索引访问(就像您已经做过的那样)或 getattr:

>>> from lxml import etree, objectify
>>> data = objectify.fromstring(
... """<gmd:MD_Metadata
... xmlns:gmd="http://www.isotc211.org/2005/gmd"
... xmlns:gco="http://www.isotc211.org/2005/gco" >
...   <gmd:fileIdentifier>
...     <gco:CharacterString>2ce585df-df23-45f6-b8e1-184e64e7e3b5</gco:CharacterString>
...   </gmd:fileIdentifier>
...   <gmd:language>
...     <gmd:LanguageCode codeList="https://www.loc.gov/standards/iso639-2/" codeListValue="ger">ger</gmd:LanguageCode>
...   </gmd:language>
... </gmd:MD_Metadata>
... """)
>>> data.fileIdentifier["{http://www.isotc211.org/2005/gco}CharacterString"]
'2ce585df-df23-45f6-b8e1-184e64e7e3b5'
>>> getattr(data.fileIdentifier, "{http://www.isotc211.org/2005/gco}CharacterString")
'2ce585df-df23-45f6-b8e1-184e64e7e3b5'
>>> 

这样做的原因显然是 {http://www.isotc211.org/2005/gco}CharacterString 不是一个有效的 Python 标识符,将不合格的查找限制为来自同一命名空间的子项是有意义的。另请参阅官方文档中的“命名空间处理”:https ://lxml.de/objectify.html#the-lxml-objectify-api

最好的,霍尔格

于 2022-02-28T07:33:35.093 回答