2012-06-13 45 views
2

假設我要與LXML XPath表達式解析如下因素XML在python中的lxml xpath,如何處理缺少的標籤?

<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蟒功能的意義上)壓縮

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

第二個包裝中丟失的max_count標籤阻止我獲得我想要的東西。

回答

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

0

你可以使用xpath找到packitem S,然後再次調用xpath(或findtext像我一樣下同),找到durationmax_count秒。不得不多次呼叫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不是很大,速度的差異可能並不重要。

+0

非常感謝你爲你花了我學習的情況下使用的時間。我已經有了一個類似於你的解決方案,並希望儘可能使用完整的xpath方法。最好的祝福 – NiL