2013-01-04 28 views
0

我試圖爲此選擇最佳方法。我擁有的是一個xml文件,最多可以包含5000個節點。每個擁有5個子節點。從XML恢復大量數據

我需要的是將其重寫到sqlite數據庫。如果我將這些xml轉換爲對象集合,然後使用這個集合將它們插入到sqlite數據庫中,那麼對於那些可能具有128RAM的較弱設備來說,這不會是矯枉過正的嗎?

或者我寧願不應該建立收集和插入值,因爲我解析XML文件?

這對用戶來說是罕見的操作。這完全是關於從xml恢復備份到設備的數據庫。

回答

2

不,不建收集在內存中。而是使用AsyncTask以及PullParser(這是當前Android庫中可用的最佳解析器)。

在您的AsyncTaskdoInBackground()中,解析出一批(如25個)對象,然後調用dbOpenHelper.bulkInsert()將整批保存到數據庫中。

當然,在這裏你必須添加一個批量插入方法到你的SQLiteOpenHelper實現來一次插入一堆行。

您可以瞭解如何爲SQLiteOpenHelper HERE編寫Bulk Insert方法。爲了簡潔起見,我添加了所需的核心方法。

try{ 
    db.beginTransaction(); 
    for each record in the list { 
    do_some_processing(); 
    if (line represent a valid entry) { 
     db.insert(SOME_TABLE, null, SOME_VALUE); 
    } 
    some_other_processing(); 
    } 
    db.setTransactionSuccessful(); 
} catch (SQLException e) { 
} finally { 
    db.endTranscation(); 
} 
+0

多麼完美的答案。謝謝! –

+0

沒問題..總是很高興幫助.. :-) –

2

是的,如果你一次加載所有的xml(從它創建一個DOM),它將需要大量的RAM。但是您可以使用SAX,StAX,PullParser等,它將按節點讀取文件,讓您知道它們何時碰到有趣的節點,並且可以通過插入將該節點保存到數據庫。解析所有5000個父節點,與DOM,每次5子節點的流

僞代碼:

while(not end node){ 
    Node n = Parser.readNextNode(); 
    saveIfInteresting(n); 
} 

saveIfInteresting(Node n){ 
    if(interesting){ 
    values = extractValues(n); 
    db.insert(values); 
    } 
} 

extractValues(Node n){ 
    //--just 5 child nodes, can do with a small DOM-- 
    Document d = buildDOM(n); 
    for(Element e in d){ 
    Values.add(e.getText()); 
    } 
    return values; 

    //OR 

    //---stream parse children too-- 
    while(not parent end node){ 
    Node n = Parser.readNext(); 
    if(n is required child){ 
     values.add(n.getText()); 
    } 
    } 
    return values; 
} 
+0

因此,它將基本上用下一個替換節點對象後,它完成了前一個? –

+0

將文件流傳遞給流解析器並調用next(),在每個next()跳轉到文件中的下一個元素(深度優先樹遍歷)。使用每個next()分析器的方法給出關於它指向的當前節點的信息。 –

+0

謝謝。兩個答案都解決了這個問題。不過,我喜歡批量的想法。對不起,我接受這兩個答案。拿起票最少:) –