2013-04-14 54 views
1

我在這裏看到了很多關於lxml解析的問題,雖然它們都非常有用,但有些問題是特定於被解析文件的結構。lxml事件解析大文件,只提取一些數據

在我來說,我有一個XML,看起來像這樣:

<documents> 
    <document> 
     <id>123456</id> 
     <element name="name"> 
      <value><![CDATA[john doe]]></value> 
     </element> 
     <element name="address"> 
      <value><![CDATA[no name street]]></value> 
     </element> 
    </document> 
</documents> 

實際的XML有很多元素,但是這僅僅是爲了舉例。 我的最終目的將是提取某些信息到CSV,使我有以下結果:

id, name, address 
123456,john doe,no name street 

但是我的問題是解析的文件,以獲得取決於「價值」元素中的值條件(如果父「元素」具有特定屬性)。

因爲我將解析的真實文件大約是8GB我認爲最好是使用lxml的iterparse來避免在存儲器中存儲大樹。

這是我現在的代碼,如果「元素」的屬性「名稱」等於列表中指定的值,則嘗試檢查下一個元素的文本時,屬性「:

from lxml import etree 

attributes = ("name", "address") 
context = etree.iterparse("test.xml", tag="document") 

for event, element in context: 
    for child in element: 
     if child.attrib.get("name") in attributes: 
      print child.getnext().text 

感謝您的幫助!

回答

1

它不是真正的「下一個」,而是後代,所以你可以再做一個循環,我想。如果value始終是唯一的子元素,你可以這樣做:

from lxml import etree 

attributes = ("name", "address") 
context = etree.iterparse("test.xml", tag="document") 

for event, element in context: 
    for child in element: 
     if child.attrib.get("name") in attributes: 
      print next(c for c in child).text 
    element.clear() # clear the subtree from the memory 

否則,你可以去,如果有點像

if child.attrib.get("name") in attributes: 
    for subchild in child: 
     if subchild.tag == 'value': 
      print subchild.text 
使裏面的一個完整的循環 for