[英]Android : Parse XML with Sax failed (goes to exception)
我正在嘗試使用SAX解析xml文件。 我不明白為什么會出現異常。 這段代碼可在我幾周前編寫的另一個應用程序中使用。 這次我創建一個XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<main>
<wifi bssid="..." >
<latitude>
...
</latitude>
<longitude>
...
</longitude>
<ssid>
...
</ssid>
</wifi>
<wifi bssid="..." >
<latitude>
...
</latitude>
<longitude>
...
</longitude>
<ssid>
...
</ssid>
</wifi>
</main>
要解析此文件,我使用以下代碼:
...
public static Vector<WifiDescription> parse(InputStream file) {
Vector<WifiDescription> wifiDescription = new Vector<WifiDescription>();
Log.d("XML", "test Parsage");
try {
// create a XMLReader from SAXParser
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
Log.e("XML", "xmlReader");
WifiHandler wifiHandler = new WifiHandler();
Log.e("XML", "WifiHandler");
xmlReader.setContentHandler(wifiHandler);
Log.e("XML", "setContentHandler");
xmlReader.parse(new InputSource(file));
Log.e("XML", "parse");
wifiDescription = wifiHandler.getWifiDescription();
Log.e("XML", "wifi description");
}
catch(Exception ex) {
Log.d("XML", "WifiParser: parse() failed");
}
return wifiDescription;
}
...
public class WifiHandler extends DefaultHandler {
public boolean isMain,isWifi,isLatitude,isLongitude,isSSID;
public int i;
public String tmpVal;
private Vector<WifiDescription> mWifiDescription;
private WifiDescription currentWifi;
/**
* @return
*/
public Vector<WifiDescription> getWifiDescription() {
Log.v("test parsage getWifiDescription","");
return mWifiDescription;
}
@Override
public void startDocument() throws SAXException {
// create new object
i=0;
Log.v("test parsage Start","");
this.mWifiDescription = new Vector<WifiDescription>();
}
@Override
public void endDocument() throws SAXException {
// nothing we need to do here
Log.v("test parsage End","");
}
@Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
throws SAXException {
Log.v("test parsage StartElement","");
if(localName.equals("main")) {
isMain=true;
Log.v("test parsage main","");
}
if(localName.equals("wifi") && isMain ) {
this.currentWifi = new WifiDescription();
tmpVal = atts.getValue(WifiDescription.MSSID);
this.currentWifi.mBSSID=tmpVal;
isWifi=true;
}
else if(localName.equals("latitude") && isWifi ) {
tmpVal = atts.getValue(WifiDescription.LATITUDE);
this.currentWifi.mLatitude=Double.parseDouble(tmpVal);
}
else if(localName.equals("longitude") && isWifi ) {
tmpVal = atts.getValue(WifiDescription.LONGITUDE);
this.currentWifi.mLongitude=Double.parseDouble(tmpVal);
}
else if(localName.equals("ssid") && isWifi ) {
tmpVal = atts.getValue(WifiDescription.SSID);
this.currentWifi.mSSID=tmpVal;
}
}
@Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
Log.v("test parsage EndElement","");
if(localName.equals("wifi")) {
//System.out.println("passe dans End landmark");
isWifi=false;
i++;
this.mWifiDescription.add(currentWifi);
}
Log.v("XML", "DONE \n");
}
}
我在mainActivity中用以下代碼調用它:
...
public void returnTableParseXml(){
try {
wifis = WifiParser.parse(getAssets().open("wifi.xml"));
}
catch (IOException e)
{
Log.d("XML Main","onCreate(): parse() failed");
return;
}
}
...
07-10 11:00:07.460: E/XML(16482): xmlReader
07-10 11:00:07.460: E/XML(16482): WifiHandler
07-10 11:00:07.460: E/XML(16482): setContentHandler
07-10 11:00:07.465: D/XML ex.getMessage(16482): null
07-10 11:00:07.465: D/XML(16482): WifiParser: parse() failed
07-10 13:33:35.480: W/System.err(29590): java.lang.NullPointerException
07-10 13:33:35.480: W/System.err(29590): at java.lang.StringToReal.parseDouble(StringToReal.java:244)
07-10 13:33:35.480: W/System.err(29590): at java.lang.Double.parseDouble(Double.java:295)
07-10 13:33:35.480: W/System.err(29590): at com.stage.ecolenavale.parser.WifiHandler.startElement(WifiHandler.java:66)
07-10 13:33:35.480: W/System.err(29590): at org.apache.harmony.xml.ExpatParser.startElement(ExpatParser.java:143)
07-10 13:33:35.480: W/System.err(29590): at org.apache.harmony.xml.ExpatParser.appendBytes(Native Method)
07-10 13:33:35.480: W/System.err(29590): at org.apache.harmony.xml.ExpatParser.parseFragment(ExpatParser.java:513)
07-10 13:33:35.480: W/System.err(29590): at org.apache.harmony.xml.ExpatParser.parseDocument(ExpatParser.java:474)
07-10 13:33:35.480: W/System.err(29590): at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:321)
07-10 13:33:35.480: W/System.err(29590): at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:279)
07-10 13:33:35.480: W/System.err(29590): at com.stage.ecolenavale.parser.WifiParser.parse(WifiParser.java:28)
07-10 13:33:35.480: W/System.err(29590): at com.stage.ecolenavale.MainActivity.returnTableParseXml(MainActivity.java:420)
07-10 13:33:35.480: W/System.err(29590): at com.stage.ecolenavale.MainActivity.onCreate(MainActivity.java:161)
我不明白為什么。 我的XML文件有問題嗎?
這是我使用SAX解析文件的代碼:
公共類WifiHandler擴展DefaultHandler {
public boolean isMain;
public int i;
public String tmpVal;
private Vector<WifiDescription> mWifiDescription;
private WifiDescription currentWifi;
/**
* @return
*/
public Vector<WifiDescription> getWifiDescription() {
Log.v("test parsage getWifiDescription","");
return mWifiDescription;
}
@Override
public void startDocument() throws SAXException {
// create new object
i=0;
Log.v("test parsage Start","");
this.mWifiDescription = new Vector<WifiDescription>();
}
@Override
public void endDocument() throws SAXException {
// nothing we need to do here
Log.v("test parsage End","");
}
@Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
throws SAXException {
Log.v("test parsage StartElement","");
if(localName.equals("main")) {
isMain=true;
Log.v("test parsage main","");
}
if(localName.equals("wifi") && isMain ) {
this.currentWifi = new WifiDescription();
tmpVal = atts.getValue(WifiDescription.MSSID);
this.currentWifi.mBSSID=tmpVal;
tmpVal = atts.getValue(WifiDescription.LATITUDE);
this.currentWifi.mLatitude=tmpVal;
tmpVal = atts.getValue(WifiDescription.LONGITUDE);
this.currentWifi.mLongitude=tmpVal;
tmpVal = atts.getValue(WifiDescription.SSID);
this.currentWifi.mSSID=tmpVal;
isWifi=true;
}
}
@Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
Log.v("test parsage EndElement","");
if(localName.equals("wifi")) {
//System.out.println("passe dans End landmark");
isWifi=false;
i++;
this.mWifiDescription.add(currentWifi);
}
Log.v("XML", "DONE \n");
}
}
public class WifiParser {
public static Vector<WifiDescription> parse(InputStream file) {
Vector<WifiDescription> wifiDescription = new Vector<WifiDescription>();
Log.d("XML", "test Parsage");
try {
// create a XMLReader from SAXParser
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
Log.e("XML", "xmlReader");
WifiHandler wifiHandler = new WifiHandler();
Log.e("XML", "WifiHandler");
xmlReader.setContentHandler(wifiHandler);
Log.e("XML", "setContentHandler");
xmlReader.parse(new InputSource(file));
Log.e("XML", "parse");
wifiDescription = wifiHandler.getWifiDescription();
Log.e("XML", "wifi description");
}
catch(Exception ex) {
Log.d("XML ex.getMessage", "" + ex.getMessage());
ex.printStackTrace();
Log.d("XML", "WifiParser: parse() failed");
}
return wifiDescription;
}
}
public void returnTableParseXml(){
try {
wifis = WifiParser.parse(getAssets().open("wifi.xml"));
}
catch (IOException e)
{
Log.d("XML Main","onCreate(): parse() failed");
return;
}
}
公共類WifiDescription {
// Description Wifi
public String mLatitude;
public String mLongitude;
public String mBSSID;
public String mSSID;
public String mName;
public static final String WIFI = "wifi";
// vector usage
public static final String LATITUDE = "latitude";
public static final String LONGITUDE ="longitude";
public static final String SSID = "ssid";
public static final String MSSID ="bssid";
public static final String NAME ="name";
}
<main>
<wifi
bssid="..:..:..:..:..:.."
latitude="..."
longitude="..."
ssid="..." >
</wifi>
...
</main>
您正在嘗試轉換XML文件中不存在的屬性值:
else if(localName.equals("latitude") && isWifi ) {
tmpVal = atts.getValue(WifiDescription.LATITUDE);
this.currentWifi.mLatitude=Double.parseDouble(tmpVal);
}
在這里, tmpVal
將為null,因此是異常。
以前,你有
<wifi
bssid="..:..:..:..:..:.."
latitude="..."
longitude="..."
ssid="..." >
</wifi>
現在,你有
<wifi bssid="..." >
<latitude>
...
</latitude>
</wifi>
因此,所需的值不是屬性,而是<lattitude>元素的字符內容。 您必須使用characters()
方法閱讀該內容。 由於您必須收集字符內容並將其讀取到endElement
的正確變量,這會使代碼更加復雜。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.