使用Android将sax在线XML文件解析为数据库

时间:2012-07-10 13:50:59

标签: android eclipse sqlite xml-parsing saxparser

我正在尝试使用我自己编写的SAX解析器解析BNR official site上找到的XML文件,并将结果返回到List中。该列表旨在存储到SQLite数据库中,以便在我的应用程序中进一步使用。

问题是,当我运行我的应用程序时,没有任何内容插入到数据库中。 以下是我目前正在使用的代码:

package com.example.myapp;
import java.io.IOException;
import java.net.URL;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;


public class myXMLReader
{
  String urlM;
  DbHandler db;

public void setDatabase (DbHandler db)
{
    this.db=db;
}

   public myXMLReader(){} 


   public List<Record> obtainCurrencyList() throws ParserConfigurationException, 
                                               SAXException, 
                                               IOException
  {
  SAXParserFactory parserFactory = SAXParserFactory.newInstance();
  SAXParser parser = parserFactory.newSAXParser();

  XMLReader xmlReader = parser.getXMLReader();
  XMLHandler currHandler = new XMLHandler();
  currHandler.setDatabase(db);
  ((org.xml.sax.XMLReader) xmlReader).setContentHandler( currHandler);

  URL url = new URL( urlM);
  ((org.xml.sax.XMLReader) xmlReader).parse(new InputSource( url.openStream()));

  return currHandler.getRecList();        
 }
 }

这里,XMLHandler是我自己写的一个类,代码如下:

  package com.example.myapp;
  import java.util.ArrayList;
  import java.util.List;

  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.DefaultHandler;

  public class XMLHandler extends DefaultHandler{

List<Record> recList = new ArrayList<Record>();
DbHandler db;
String data;
String rate;
String moneda;
String multi;
boolean brate;

public void setDatabase (DbHandler db)
{
    this.db=db;
}


public void startElement( String theNamespaceURI, 
        String theLocalName,
        String theQName, 
        Attributes theAtts) throws SAXException 
        { 


    if  (theLocalName.equals("Cube"))

    {
        data = theAtts.getValue("date");
    }

    //if (data.equals(db.getLastRecord().data)==false)
    {

        if(theLocalName.equals("Rate"))
        {
            moneda = theAtts.getValue("currency");
            multi = theAtts.getValue("multiplier");
            if (multi==null) multi="1";
            //rate = new String();
            brate=true;

        }

    }
        }


  public void endElement(String uri, String localName, String qName) throws 
  SAXException {
    //if (data.equals(db.getLastRecord().data)==false)
    {
        if (localName.equals("Rate"))
            recList.add(new Record( moneda, multi, rate, data));
    }
};


public void characters(char[] ch, int start, int length) throws SAXException 
{
    if (data.equals(db.getLastRecord().data)==false)
    {
        if (brate)
        {   
            rate = new String(ch,start,length);
            brate = false;
        }
    }
};



List<Record> getRecList()
{
    return recList;
} 
  }

好的,这里包含与数据库相关的函数,在DbHandler类中:

package com.example.myapp;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DbHandler
{
private DatabaseHelper mDbHelper;
SQLiteDatabase mDb;
private static Context mCtx;
// All Static variables
// Database Version
public static final int DATABASE_VERSION = 1;

// Database Name
public static final String DATABASE_NAME = "CursBNR";

// Contacts table name
public static final String TODAY = "CursCurent";

// Contacts Table Columns names
public static final String KEY_ID = "_id";
public static final String KEY_MONEDA = "Moneda";
public static final String KEY_MULTI = "Multi";
public static final String KEY_RATA = "Rata";
public static final String KEY_DATA = "Data";


public static class DatabaseHelper extends SQLiteOpenHelper{

    public DatabaseHelper(Context context) {
        super(mCtx, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // Creating Tables
    @Override
    public void onCreate(SQLiteDatabase db)
    {
String CREATE_TODAY = "CREATE TABLE " + TODAY + "("+ KEY_ID + " INTEGER PRIMARY KEY
 AUTOINCREMENT," + KEY_MONEDA + " TEXT,"+ KEY_MULTI + " TEXT,"+ KEY_RATA + " TEXT," + 
KEY_DATA + " TEXT" + ");";
        db.execSQL(CREATE_TODAY);
        ;
    }

    // Upgrading database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TODAY);
        // Create tables again
        onCreate(db);
    }
}

/**init context, open and close database*/

public DbHandler initcontext(Context ctx) {
    mCtx = ctx;
    return this;
}

public DbHandler open() throws SQLException {
    mDbHelper = new DatabaseHelper(mCtx);
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

public void close() {
    mDbHelper.close();
}




/**
 * All CRUD(Create, Read, Update, Delete) Operations
 */

// Adding new contact
void addRecord(String MONEDA, String MULTI, String RATA, String DATA) {
    try{
        mDb.execSQL("INSERT INTO "+TODAY+"
('"+KEY_MONEDA+"','"+KEY_MULTI+"','"+KEY_RATA+"','"+KEY_DATA+"') VALUES('"+MONEDA+"', 
'"+MULTI+"', '"+RATA+"', '"+DATA+"');");
    }catch(Exception ex){
        ex.printStackTrace();
    }
}

// Updating single contact
public void updateRecord(String MONEDA, String MULTI, String RATA, String DATA) 
{
    try{
        mDb.execSQL("UPDATE "+TODAY+" SET "+KEY_MONEDA+"='"+MONEDA+"', 
"+KEY_MULTI+"='"+MULTI+"', "+
                KEY_RATA+"='"+RATA+"',"+KEY_DATA+"='"+DATA+"' 
WHERE "+KEY_MONEDA+"='"+MONEDA+"';");
    }catch(Exception ex){
        ex.printStackTrace();
    }
}  


/** 
 * DELETE all students
 */
public void dropAllRecords(){
    try{
        mDb.delete(TODAY, null, null);
    }catch(SQLException ex){
        ex.printStackTrace();
    }   
}

public void deleteRecords (int ID)
{
    try
    {
        mDb.execSQL("DELETE * FROM"+TODAY+" WHERE "+KEY_ID+"='"+ID+"'");
    }
    catch (SQLException ex)
    {
        ex.printStackTrace();
    }
}

public Record getLastRecord(){

    String query = "SELECT * FROM "+TODAY+" WHERE "+KEY_ID+"=(SELECT 
MAX("+KEY_ID+") FROM "+TODAY+");";
    Cursor cursor = null;
    Record record = new Record();

    try{

        cursor = this.mDb.rawQuery(query, null);
        cursor.moveToFirst();
        record.setID(cursor.getString(0));
        record.setMoneda(cursor.getString(1));
        record.setMulti(cursor.getString(2));
        record.setRata(cursor.getString(3));
        record.setData(cursor.getString(4));    
    }catch(Exception ex){
        ex.printStackTrace();
    }

        //close cursor avoiding memory leaks
    if(!cursor.isClosed())
        cursor.close();

    return record;

}

public int getreccount(){
    //allocate memory
    String query = "SELECT COUNT("+KEY_MONEDA+") FROM "+TODAY;
    int result = 0;
    Cursor cursor = null;
    //fetch result
    try{
        cursor = this.mDb.rawQuery(query, null);
        cursor.moveToFirst();
        result = cursor.getInt(0);
    }catch(Exception ex){
        cursor.close();
        ex.printStackTrace();
    }

    //close cursor avoiding memory leaks
    if(!cursor.isClosed())
        cursor.close();

    return result;
}

起初它似乎工作,直到我把条件:if(data.equals(db.getLastRecord()。data)== false),whick意味着检查最后记录的项目是否具有相同的日期作为xml中的项目。如果不是,它们应该被插入到数据库中,我通过这个编码来完成:

注意:这是从我的ProjectActivity.java中获取的,这是OnClick()函数的一小部分。

myXMLReader XML= new myXMLReader();
XML.setDatabase(dbHandler);
XML.urlM="http://www.bnr.ro/nbrfxrates.xml";


    //create database if necessary, update database

    try
    {
        List <Record> reclist = XML.obtainCurrencyList();


        if (reclist.isEmpty()==false)
        {
            //database gets updated

            for (int i=0; i<reclist.size(); i++)
            {
                dbHandler.addRecord(reclist.get(i).moneda, 
reclist.get(i).multi, reclist.get(i).rata, reclist.get(i).data);    

            }
        } 


    }
    catch (Exception e) 
    {
        // TODO: handle exception
        Log.i("Exceptie", "Exceptie");
        e.printStackTrace();
    }

我检查了所有变量是否已通过Eclipse调试界面正确设置,并且我得到的值似乎是正确的。我有一种感觉,如果在具有空表的数据库上运行,getLastRecord()函数可能具有不正确的行为,但我无法弄清楚原因。正如您在代码中看到的那样,我已经尝试对条件进行注释,但仍然没有任何内容返回到数据库中。

非常感谢您提出的任何建议,感谢您抽出宝贵时间!

1 个答案:

答案 0 :(得分:0)

我可能正在阅读这个错误,但看起来你正在解析XML然后插入结果但是你试图从数据库中读取“最后一条记录”,同时仍然在解析XML(即插入之前)任何东西)。

尝试保留指向添加到reclist的最后一条记录的/指针副本并使用if(lastRec !=null && data.equals(lastRec.data))