【问题标题】:Dealing with missing elements in xml document处理 xml 文档中缺少的元素
【发布时间】:2014-03-28 14:51:30
【问题描述】:

我有一些 XML,其中的一个片段如下所示:

<osgb:departedMember>
<osgb:DepartedFeature fid='osgb4000000024942964'>
<osgb:boundedBy>
<gml:Box srsName='osgb:BNG'>
<gml:coordinates>188992.575,55981.029 188992.575,55981.029</gml:coordinates>
</gml:Box>
</osgb:boundedBy>
<osgb:theme>Road Network</osgb:theme>
<osgb:reasonForDeparture>Deleted</osgb:reasonForDeparture>
<osgb:deletionDate>2014-02-19</osgb:deletionDate>
</osgb:DepartedFeature>
</osgb:departedMember>

我正在解析它:

departedmembers = doc_root.findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}departedMember')
for departedMember in departedMembers:
    findWhat='{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}DepartedFeature'
    fid = int(departedmember.find(findWhat).attrib['fid'].replace('osgb', ''))
    theme=departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}theme')[0].text    
    reason=departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}reasonForDeparture')[0].text
    date=departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}deletionDate')[0].text

有时原因或日期或两者都为空,即缺少元素,而不仅仅是内容为空。根据 XSD,这是合法的,但我在尝试选择不存在元素的文本时遇到属性错误。为了解决这个问题,我将原因和日期行放在 try 中,除了块,例如:

try:
    date=departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}deletionDate')[0].text
except:
    pass

这可行,但我讨厌像这样使用 except/pass,所以它让我想知道是否有更好的方法来解析这样的文档,其中某些元素是可选的。

【问题讨论】:

    标签: python xml xml.etree


    【解决方案1】:

    由于您只对findall 的第一个元素感兴趣,您可以将findall(x)[0] 替换为find(x)。此外,如果你想避免 try/except 块,你可以使用三元。

    departedmembers = doc_root.findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}departedMember')
    for departedMember in departedMembers:
        ...
        date = departedmember[0].find('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}deletionDate')
        date = None if date == None else date.text # Considering you want to set the element to None if it was not found
    

    【讨论】:

      【解决方案2】:

      是的,问题不在于搜索方法,而在于没有返回元素时的引用。您可以这样编写代码:

      results = departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}deletionDate')
      
      if results:
          date = results[0].text
      else:
          # there is no element,
          # do what you want in this case
      

      【讨论】:

      • 这肯定比 try/except 更干净。不过,我部分地想知道,这是否是解析大型 xml 文档的最佳方法,或者我是否应该在 xmltree 中使用 xpath 之类的东西。
      • @JohnBarça,我发现 xpath 更易于维护
      • @Luis,谢谢,我会尽快尝试。我有千兆字节的 XML 需要快速解析,并且在短时间内了解非常出色的 xmltree 库的各种错综复杂的内容很有趣。
      猜你喜欢
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      相关资源
      最近更新 更多