簡體   English   中英

Android:使用Sax解析XML失敗(進入異常)

[英]Android : Parse XML with Sax failed (goes to exception)

我正在嘗試使用SAX解析xml文件。 我不明白為什么會出現異常。 這段代碼可在我幾周前編寫的另一個應用程序中使用。 這次我創建一個XML文件:

wifi.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>

要解析此文件,我使用以下代碼:

WifiParser.java

    ...
    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;
}
    ...

WifiHandler .java

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中用以下代碼調用它:

MainActivity.java

    ...
    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

ex.printStackTrace();

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.java


公共類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");
}

}

WifiParser.java


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;
}

}

MainActivity.java


    public void returnTableParseXml(){
    try {
        wifis = WifiParser.parse(getAssets().open("wifi.xml"));
    }
    catch (IOException e) 
    {
        Log.d("XML Main","onCreate(): parse() failed");
        return;
    }
}

WifiDescription.java


公共類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";

}

Wifi.xml


<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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM