2

从我找到的所有教程(包括 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 编程的初学者,活动/布局/服务之间的关系......有点难以理解:(

问题:如何在我的活动中调用/执行这个?

4

4 回答 4

1

createDataBase()方法应该在类onCreate()的方法内部调用XMLtoSQLite

于 2013-09-20T09:40:10.853 回答
1

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

数据库

恕我直言,您必须很好地创建数据库类,因此请遵循Vogella 的指南;它非常有用,并详细解释了有关数据库的所有内容。

从网络下载您的数据

将来(见上面的评论)你需要从网上下载你的数据,所以使用AsyncTask类来连接到一个站点,然后下载你需要的所有东西;如果你不知道这门课,请阅读这个官方指南

解析 XML

你必须解析你的 XML:你可以使用这个指南,或者这个。我使用 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);
}
于 2013-09-20T12:30:07.857 回答
1

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

原因一:为了性能原因二:为了代码的清晰

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

架构示例:

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 - 创建de数据库并且表为空

3 - 填写表格

4 - 在一个简单的缓存中获取你需要的数据(List, HashMap, ArrayList, ...)

5 - 在需要时显示/使用这些数据(如果可用)

注意 :

1 - 下载应该在另一个线程中完成(线程、异步任务、服务......)

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

于 2013-09-20T09:41:01.573 回答
0

感谢大家提供的所有答案,以及其他资源,这些答案有助于找到解决我的问题的方法。

基本上我需要用 XML 文件构建一个数据库,然后将这个数据库导出到另一个项目中;这样我就不需要直接将 XML 与我的最终应用程序一起发送,也不会冒犯这样一个事实,即当在廉价智能手机上运行时,来自 XML 的数据库填充会挂起。

也就是说,让我们深入研究对我有用的代码:) 在我的主布局中,我创建了一个 ID 为“createButton”的按钮。

主要的.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;
    }
}
于 2013-10-05T09:33:05.337 回答