我正在尝试为此选择最佳方法。我拥有的是一个可能包含多达 5000 个节点的 xml 文件。每个拥有 5 个子节点。
我需要的是把它重写到 sqlite 数据库。如果我将这些 xml 转换为对象集合,然后使用该集合将它们插入 sqlite 数据库,那么对于可能具有 128RAM 的较弱设备来说,这不是矫枉过正吗?
或者我不应该在解析 XML 文件时构建集合并插入值?
这对用户来说将是罕见的操作。这一切都是关于将备份从 xml 恢复到设备的数据库。
是的,如果您一次加载所有 xml(从中创建一个 DOM),它将占用大量 RAM。但是您可以使用 SAX、StAX、PullParser 等,它们将逐个节点读取文件,让您知道它们何时遇到有趣的节点,您可以通过插入将该节点保存到数据库。
Stream 解析所有 5000 个父节点的伪代码,每 5 个子节点使用 DOM:
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;
}
不,不要在内存中构建集合。而是使用AsyncTask
with PullParser
(这是目前 Android 库中可用的最佳解析器)。
在doInBackground()
您的 中AsyncTask
,解析出一个批次(比如 25 个)对象,然后调用dbOpenHelper.bulkInsert()
一次将整个批次保存到您的数据库中。
当然,在这里你必须在你的 SQLiteOpenHelper 实现中添加一个批量插入方法来一次插入一堆行。
您可以在此处了解如何为您的 SQLiteOpenHelper 编写批量插入方法。为了简洁起见,我添加了所需的核心方法。
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();
}