我目前正在尝试使用我自己编写的 SAX 解析器解析在BNR 官方网站上找到的 XML 文件,并将结果返回到列表中。该列表旨在存储到 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() 函数可能会有不正确的行为,但我不知道为什么。正如您在代码中看到的那样,我已经尝试对条件进行注释,但仍然没有任何内容返回到数据库中。
非常感谢您提出的任何建议,感谢您抽出宝贵的时间!