繁体   English   中英

使用LXML和Python解析空白XML标签

[英]Parsing blank XML tags with LXML and Python

以以下格式解析XML文档时:

<Car>
    <Color>Blue</Color>
    <Make>Chevy</Make>
    <Model>Camaro</Model>
</Car>

我使用以下代码:

carData = element.xpath('//Root/Foo/Bar/Car/node()[text()]')
parsedCarData = [{field.tag: field.text for field in carData} for action in carData]
print parsedCarData[0]['Color'] #Blue

如果标签为空,则此代码将无效:

<Car>
    <Color>Blue</Color>
    <Make>Chevy</Make>
    <Model/>
</Car>

使用与上面相同的代码:

carData = element.xpath('//Root/Foo/Bar/Car/node()[text()]')
parsedCarData = [{field.tag: field.text for field in carData} for action in carData]
print parsedCarData[0]['Model'] #Key Error

我将如何解析这个空白标签。

您要放置一个[text()]过滤器,该过滤器显式地仅询问具有文本节点的元素...然后,当它不给您没有文本节点的元素时,您会感到不满意?

除去该过滤器,您将获得模型元素:

>>> s='''
... <root>
...   <Car>
...     <Color>Blue</Color>
...     <Make>Chevy</Make>
...     <Model/>
...   </Car>
... </root>'''
>>> e = lxml.etree.fromstring(s)
>>> carData = e.xpath('Car/node()')
>>> carData
[<Element Color at 0x23a5460>, <Element Make at 0x23a54b0>, <Element Model at 0x23a5500>]
>>> dict(((e.tag, e.text) for e in carData))
{'Color': 'Blue', 'Make': 'Chevy', 'Model': None}

就是说-如果您的近期目标是遍历树中的节点,则可以考虑使用lxml.etree.iterparse() ,这将避免尝试在内存中构建完整的DOM树,否则将比构建一棵树,然后使用XPath对其进行迭代。 (考虑一下SAX,但没有疯狂而痛苦的API)。

使用iterparse实施可能看起来像这样:

def get_cars(infile):
    in_car = False
    current_car = {}
    for (event, element) in lxml.etree.iterparse(infile, events=('start', 'end')):
        if event == 'start':
            if element.tag == 'Car':
                in_car = True
                current_car = {}
            continue
        if not in_car: continue
        if element.tag == 'Car':
            yield current_car
            continue
        current_car[element.tag] = element.text

for car in get_cars(infile = cStringIO.StringIO('''<root><Car><Color>Blue</Color><Make>Chevy</Make><Model/></Car></root>''')):
  print car

...这是更多代码,但是(如果我们不使用StringIO作为示例),它可以处理比内存大得多的文件。

我不知道lxml内部是否有更好的解决方案,但是您可以使用.get()

print parsedCarData[0].get('Model', '')

我会捕捉到异常:

try:
    print parsedCarData[0]['Model']
except KeyError:
    print 'No model specified'

Python中的异常并非与其他语言中的异常相同,在异常中,它们与错误条件的联系更为严格。 相反,根据设计,它们通常是模块正常使用的一部分。 例如,迭代器引发StopIteration以信号通知它已到达迭代结束。

编辑:如果您确定只有此项目可以为空,@ CharlesDuffy正确使用get()可能更好。 但是总的来说,我会考虑使用异常来轻松处理各种异常输出。

解决方案:使用try/except块捕获关键错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM