使用XML填充SQLite并在Activity中集成

时间:2013-09-20 09:30:51

标签: android xml eclipse sqlite android-activity

从我找到的所有教程(包括Stackoverflow中的答案)中,我找不到一个完整的教程,展示如何实现XML到SQLite填充。 我创建了一个数据库助手,但我不知道如何将它集成到我的活动中。我想做的是;应用程序启动后,应立即使用XML填充数据库。

XML

我在“res \ xml”文件夹中有一个XML文件“amawal_posts.xml”,其中包含我想要在数据库中填充的一些条目。

<?xml version="1.0" encoding="utf-8"?>
<database name="npma_amawal" >
    <!-- Table wp_posts -->
    <table name="wp_posts" >
        <column name="ID" >948</column>
        <column name="post_content" >اورغ</column>
        <column name="post_title" >ure</column>
    </table>
    <table name="wp_posts" >
        <column name="ID" >46</column>
        <column name="post_content" >adlis g llan iwaliwn FR: dictionnaire.</column>
        <column name="post_title" >amawal</column>
    </table>
</database>

此XML包含超过4000条记录。

SQLiteOpenHelper

以下是“XMLtoSQLite.java”的内容

package com.np.amawalandroiddb;

import java.io.IOException;

import org.xmlpull.v1.XmlPullParserException;

import com.np.amawalandroiddb.R;

import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class XMLtoSQLite extends SQLiteOpenHelper {

    private final Context fContext;

    // Set TAG for error catching
    public static String TAG = "XMLtoSQLite";

    // Set database columns
    public static String column_ID = null;
    public static String column_post_content = null;
    public static String column_post_title = null;

    public XMLtoSQLite(Context context) {
        super(context, "amawal", null, 1);
        fContext = context;
    }


    public void createDataBase (SQLiteDatabase db) throws IOException {
        db.execSQL("CREATE TABLE amawal_posts (" + "ID INTEGER PRIMARY KEY,"
                + "post_content TEXT," + "post_content TEXT" + ");");

        // Add default records amawal_posts
        ContentValues Columns = new ContentValues();

        // Get XML resource file
        Resources res = fContext.getResources();

        // Open XML file
        int eventType = -1;
        while (eventType != XmlResourceParser.END_DOCUMENT) {
            XmlResourceParser database = res.getXml(R.xml.amawal_posts);
            String name = database.getText();
            Log.d(TAG, name);

            try {
                if (database.getEventType() == XmlResourceParser.START_TAG) 
                {
                    String s = database.getName();

                    if (s.equals("table")) 
                    {
                        database.next(); // moving to the next node
                        if (database.getName() != null  && database.getName().equalsIgnoreCase ( "column")) 
                        {
                            column_ID = database.getText(); // to get  value getText() method should be used
                            database.next();

                            column_post_content = database.getText();
                            database.next();

                            column_post_title = database.getText(); 

                            // Insert the values inside the DB
                            Columns.put("ID", column_ID);
                            Columns.put("post_content", column_post_content);
                            Columns.put("post_title", column_post_title);

                            db.insert("amawal", null, Columns);

                        }

                        Log.d(TAG, column_ID);
                        Log.d(TAG, column_post_content);
                        Log.d(TAG, column_post_title);
                    }
                }
            } 
            //Catch errors
            catch (XmlPullParserException e)
            {       
                Log.e(TAG, e.getMessage(), e);
            }
            catch (IOException e)
            {
                Log.e(TAG, e.getMessage(), e);

            }           
            finally
            {           
                //Close the XML file
                database.close();
            }
        }
    }

    /* Update database to latest version */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Crude update, make sure to implement a correct one when needed.

        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS animals");
        onCreate(db);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub

    }

}

我的主要活动

“MainActivity.java”的内容

package com.np.amawalandroiddb;


import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Begin DB work
        XMLtoSQLite db = new XMLtoSQLite(this);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

成为Java编程的初学者会使活动/布局/服务之间产生关系......有点难以理解:(

问题:如何在我的Activity中调用/执行它?

4 个答案:

答案 0 :(得分:1)

应在createDataBase()

onCreate()方法内调用

XMLtoSQLite方法

答案 1 :(得分:1)

您不应将它们放在xml文件中。

理由一:表现 原因二:为了清晰的代码

有用链接:http://www.vogella.com/articles/AndroidSQLite/article.html

Architechture示例:

表示单个表的anObject.java文件(onCreate和onUpdate方法应该在这里自定义,toString(),...) 管理该表的AnObjectManger.java文件,执行请求,.. AnOpenHelperDataBase.java简化了sqlite的使用并执行基本操作

请注意,要创建数据库,您只需要以下示例:

public DatabaseOpenHelper(Context context, CursorFactory factory) {

        super(context, DATA_BASE_NAME, factory, DATABASE_VERSION);
    }

编辑:

如果你仍然希望保持你的方法是操作顺序

1 - 下载数据

2 - 创建数据库,表格为空

3 - 填写表格

4 - 在简单缓存中获取所需数据(List,HashMap,ArrayList,...)

5 - 如果可用,则在您需要时显示/使用这些数据

注意:

1 - 下载应该在另一个线程(Thread,Asynctask,service ...)

中完成

2 - 数据库上的操作通常也应该在另一个线程中完成

答案 2 :(得分:1)

我认为最好的方法是遵循一些有用的指南。让我们将问题分成更简单的部分:

<强>数据库

恕我直言,你必须很好地创建你的数据库类,所以请关注Vogella's guide;它非常有用,详细解释了数据库的所有内容。

从网上下载您的数据

将来(请参阅上面的评论)您需要从网上下载数据,因此请使用 AsyncTask 类连接到网站,然后下载您需要的所有内容;如果你不懂这门课,请阅读official guide

解析XML

您必须解析XML:您可以使用this guidethis one。我使用的是DocumentBuilder,但我的XML文件与你的不同:

...
String errorCode = null;
Document changes;
try {
    // URL were lies some xml-data
    URL url = new URL(params[0]);

    // Creating a document
    InputSource is = new InputSource(url.openStream());
    DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    changes = db.parse(is);
    changes.getDocumentElement().normalize();

    // Searching AUTHKEY in created document
    NodeList root = changes.getElementsByTagName("Auth");
    Element myRoot = (Element) root.item(0);
    errorCode = myRoot.getAttribute("ErrorCode");
    auth = myRoot.getAttribute("Key");
} catch (IOException e) {
    errorCode = null;
} catch (ParserConfigurationException e) {
    errorCode = null;
} catch (SAXException e) {
    errorCode = null;
} catch (Exception e) {
    errorCode = null;
}
...

我希望你能找到有用的每一个环节。

修改

在您的MainActivity上添加此内容(当然,在您更改代码后):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    String url = "http://myUrlWhereDataIsStored.com";

    // Creating database
    MyDatabase database = new MyDatabase(this);
    // Populating database
    new MyAsyncTask().execute(url);
}

答案 3 :(得分:0)

感谢大家的所有答案,除了其他资源之外,还有助于找到问题的解决方案。

基本上我需要用XML文件构建数据库,然后将这个数据库导出到另一个项目中;通过这种方式,我不需要直接使用我的最终应用程序发送XML,也不会冒险在廉价智能手机上运行时从XML中获取数据库的情况会被挂起..

那说,让我们挖掘适合我的代码:) 在我的主要布局中,我创建了一个ID为“createButton”的按钮。

main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".XMLtoDB" >

<Button
    android:id="@+id/createButton"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/create_database" />

<ListView
    android:id="@+id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_below="@+id/createButton" />

然后在我的主要活动java文件中,我在单击时设置了按钮,它使用SQLiteOpenHelper从XML填充数据库。

XMLtoDB.java

ListView listView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);



    final Button createbtn = (Button) findViewById(R.id.createButton);
    createbtn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            SQLiteDatabase db = new DbHelper(getApplicationContext()).getWritableDatabase();

            if (db != null) {
                Toast.makeText(XMLtoDB.this, "Database is created!", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(XMLtoDB.this, "Error creating database!", Toast.LENGTH_SHORT).show();
            }
        }
    });

}

Dbhelper.java

/*
* How to extract the generated DataBase in DDMS?
 * First of all, delete the old database by going to the emulator app amanger
 * then clear cash.
 * Then in DDMS re-select the device in the left pane. For some reasons, 
 * it needs to be refreshed and the previous selection is invalid.
 * */
package com.np.amawalandroid.db;

import java.io.IOException;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;

import com.np.amawalandroid.xml.XMLParser;
import com.np.amawalandroid.xml.XMLParserObject;

public class DbHelper extends SQLiteOpenHelper implements BaseColumns {

public static final String DB_TEST = "amawal.sqlite";
public static final String TABLE_NAME = "wp_posts";
public static final String ID = "ID";
public static final String post_content = "post_content";
public static final String post_title = "post_title";
private static Context mContext;
List<XMLParserObject> posts = null;

public DbHelper(Context context) {
    super(context, DB_TEST, null, 1);
    mContext = context;
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + ID + " INTEGER, " + post_content + " TEXT, "
            + post_title + " TEXT);");

    // Insert data from XML
    XMLParser parser = new XMLParser();
    try {
        posts = parser.parse(mContext.getAssets().open("wp_posts.xml"));

        for (XMLParserObject post : posts) {
            //Toast.makeText(mContext, post.getpostTitle(), Toast.LENGTH_SHORT).show();

            ContentValues values = new ContentValues();

            values.put(ID, post.getId());
            values.put(post_content, post.getPostContent());
            values.put(post_title, post.getpostTitle());
            db.insert(TABLE_NAME, ID, values);

        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
    onCreate(db);
}

}

解析我的XML文件,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<pma_xml_export version="1.0" xmlns:pma="http://www.phpmyadmin.net/some_doc_url/">
<database name="npma_amawal">
       <table name="wp_posts">
            <column name="ID">46</column>
            <column name="post_content">adlis g llan iwaliwn</column>
            <column name="post_title">amawal</column>
        </table>

我用

XMLParser.java

package com.np.amawalandroid.xml;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

public class XMLParser {
    List<XMLParserObject> posts;
    private XMLParserObject post_ref;

    public XMLParser() {
        posts = new ArrayList<XMLParserObject>();
    }

    public List<XMLParserObject> parse(InputStream is) {
        XmlPullParserFactory factory = null;
        XmlPullParser parser = null;
        try {
            factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(true);
            parser = factory.newPullParser();

            parser.setInput(is, null);

            int eventType = parser.getEventType();
            while (eventType != XmlPullParser.END_DOCUMENT) {
                String tagname = parser.getName();
                // System.out.println("=======" + tagname + "============");
                switch (eventType) {
                case XmlPullParser.START_TAG:
                    // if <table> create a new instance of post
                    if (tagname.equalsIgnoreCase("table")) {
                        post_ref = new XMLParserObject();
                    }
                    // if <column>
                    if (tagname.equalsIgnoreCase("column")) {
                        if (parser.getAttributeValue(null, "name").equalsIgnoreCase("ID")) {
                            // System.out.println("ID found! ");
                            post_ref.setId(Integer.parseInt(parser.nextText()));

                        } else if (parser.getAttributeValue(null, "name").equalsIgnoreCase("post_content")) {
                            // System.out.println("post_content found! ");
                            post_ref.setPostContent(parser.nextText());

                        } else if (parser.getAttributeValue(null, "name").equalsIgnoreCase("post_title")) {
                            // System.out.println("post_title found! ");
                            post_ref.setpostTitle(parser.nextText());
                        }
                    }
                    break;

                case XmlPullParser.END_TAG:
                    if (tagname.equalsIgnoreCase("table")) {
                        posts.add(post_ref);
                        // System.out.println("Posts so far " + post_ref);
                    }
                    break;

                default:
                    break;
                }
                eventType = parser.next();
            }

        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return posts;
    }
}

XMLParserObject.java

public class XMLParserObject {

    private int ID;
    private String post_title;
    private String post_content;

    public int getId() {
        return ID;
    }

    public void setId(int ID) {
        this.ID = ID;
    }

    public String getpostTitle() {
        return post_title;
    }

    public void setpostTitle(String post_title) {
        this.post_title = post_title;
    }

    public String getPostContent() {
        return post_content;
    }

    public void setPostContent(String post_content) {
        this.post_content = post_content;
    }

    @Override
    public String toString() {
        return ID + ": " + post_title + "\n" + post_content;
    }
}