python中的lxml xpath,如何处理丢失的标记?

2024-03-29 12:49:42 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我想用lxml xpath表达式解析下面的xml

<pack xmlns="http://ns.qubic.tv/2010/item">
    <packitem>
        <duration>520</duration>
        <max_count>14</max_count>
    </packitem>
    <packitem>
        <duration>12</duration>
    </packitem>
</pack>

这是在http://python-thoughts.blogspot.fr/2012/01/default-value-for-text-function-using.html上可以找到的变体

如何实现对不同元素的解析,一旦压缩就可以得到这些元素(在zip或izip python函数意义上)

[(520,14),(12,无)]

是吗?在

第二个packitem中缺少的max_count标记使我无法得到我想要的东西。在


Tags: http元素表达式countxmltvlxmlxpath
2条回答
def lxml_empty_str(context, nodes):
    for node in nodes:
        node.text = node.text or ""
    return nodes

ns = etree.FunctionNamespace('http://ns.qubic.tv/lxmlfunctions')
ns['lxml_empty_str'] = lxml_empty_str

namespaces = {'i':"http://ns.qubic.tv/2010/item",
          'f': "http://ns.qubic.tv/lxmlfunctions"}
packitems_duration = root.xpath('f:lxml_empty_str('//b:pack/i:packitem/i:duration)/text()',
namespaces={'b':billing_ns, 'f' : 'http://ns.qubic.tv/lxmlfunctions'})
packitems_max_count = root.xpath('f:lxml_empty_str('//b:pack/i:packitem/i:max_count)    /text()',
namespaces={'b':billing_ns, 'f' : 'http://ns.qubic.tv/lxmlfunctions'})
packitems = zip(packitems_duration, packitems_max_count)

>>> packitems
[('520','14'), ('','23')]

http://python-thoughts.blogspot.fr/2012/01/default-value-for-text-function-using.html

您可以使用xpath来找到packitem,然后再次调用xpath(或如下所述findtext)来找到duration和{}。多次调用xpath可能不会太快,但它是有效的。在

import lxml.etree as ET

content = '''<pack xmlns="http://ns.qubic.tv/2010/item">
    <packitem>
        <duration>520</duration>
        <max_count>14</max_count>
    </packitem>
    <packitem>
        <duration>12</duration>
    </packitem>
</pack>
'''

def make_int(text):
    try:
        return int(text)
    except TypeError:
        return None

namespaces = {'ns' : 'http://ns.qubic.tv/2010/item'}
doc = ET.fromstring(content)
result = [tuple([make_int(elt.findtext(path, namespaces = namespaces))
                           for path in ('ns:duration', 'ns:max_count')])
          for elt in doc.xpath('//ns:packitem', namespaces = namespaces) ]
print(result)
# [(520, 14), (12, None)]

另一种方法是使用SAX解析器。这可能会快一点,但需要更多的代码,如果XML不是很大,那么速度差异可能就不重要了。在

相关问题 更多 >