简体   繁体   中英

How do parse xml in android using SAX Parser?

I'm a noob to android and I'm trying to learn how to parse xml with the SAX parser. I've written a test application to try to implement it, but i can't seem to make it work. I want my textview to display corresponding values from an xml but it's not working. Can anyone help?

Parser

public class ParseTestActivity extends Activity implements View.OnClickListener {
/** Called when the activity is first created. */
final static String TAG = "spotxml";
TextView tv;
WebView xml;
Button help, help2;
int livespot = 0;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    tv = (TextView) findViewById(R.id.textView1parsed);
    help = (Button) findViewById(R.id.button1);
    help2 = (Button) findViewById(R.id.button2);
    help.setOnClickListener(this);
    help2.setOnClickListener(this);
    xml = (WebView) findViewById(R.id.webView1);

    try{
    xml.loadUrl("http://www.xmlcharts.com/cache/precious-metals.xml");
    }catch (Exception e){
        e.printStackTrace();
    }


    try{
        URL xmlcharts = new URL("http://www.xmlcharts.com/cache/precious-metals.xml");  
        //InputSource local = new InputSource(getResources().openRawResource(R.raw.preciousmetals));
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        XMLReader xr = sp.getXMLReader();
        HandlingXMLStuff doingWork = new HandlingXMLStuff();
        xr.setContentHandler(doingWork);
        xr.parse(new InputSource(xmlcharts.openStream()));  
        //xr.parse(local);
        XMLDataCollected information = doingWork.getInformation(); 
        //String information = doingWork.getInformation();
        tv.setText(information.toString());
        livespot = Integer.parseInt(information.toString());
    }catch(Exception e){
        Toast.makeText(ParseTestActivity.this, "Error", Toast.LENGTH_LONG).show();
        Log.e(TAG, "WeatherQueryError", e);
    }




}


@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    switch(v.getId()){
    case R.id.button1:
        try{
            URL xmlcharts = new URL("http://www.xmlcharts.com/cache/precious-metals.xml");  
            //InputSource local = new InputSource(getResources().openRawResource(R.raw.preciousmetals));
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
            XMLReader xr = sp.getXMLReader();
            HandlingXMLStuff doingWork = new HandlingXMLStuff();
            xr.setContentHandler(doingWork);
            xr.parse(new InputSource(xmlcharts.openStream()));  
            //xr.parse(local);
            XMLDataCollected information = doingWork.getInformation();
            //String information = doingWork.getInformation();
            tv.setText(information.toString());
            livespot = Integer.parseInt(information.toString());
        }catch(Exception e){
            Toast.makeText(ParseTestActivity.this, "Error", Toast.LENGTH_LONG).show();
            Log.e(TAG, "WeatherQueryError", e);
        }
        break;
    case R.id.button2:
        try{                
            //URL xmlcharts = new URL("http://www.xmlcharts.com/cache/precious-metals.xml");    
            InputSource local = new InputSource(getResources().openRawResource(R.raw.preciousmetals));
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
            XMLReader xr = sp.getXMLReader();
            HandlingXMLStuff doingWork = new HandlingXMLStuff();
            xr.setContentHandler(doingWork);
            //xr.parse(new InputSource(xmlcharts.openStream()));    
            xr.parse(local);
            XMLDataCollected information = doingWork.getInformation();
            //String information = doingWork.getInformation();
            tv.setText(information.toString());
            livespot = Integer.parseInt(information.toString());
        }catch(Exception e){
            Toast.makeText(ParseTestActivity.this, "Error", Toast.LENGTH_LONG).show();
            Log.e(TAG, "WeatherQueryError", e);
        }
        break;
}
}}

Content Handler

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



public class HandlingXMLStuff extends DefaultHandler {

        private boolean in_prices = false;
        private boolean in_pricelist = false;
        private boolean in_uspricegold = false;
        private boolean in_uspricesilver = false;
        String gs = null;
        String ss = null;


    private XMLDataCollected info = new XMLDataCollected();

    //public String getInformation(){
    //  return info.datatoString();
    //}
    public XMLDataCollected getInformation(){
        return this.info;
    }



    @Override
    public void startDocument() throws SAXException {
    this.info = new XMLDataCollected();
    }

    @Override
    public void endDocument() throws SAXException {
              // Nothing to do
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        // TODO Auto-generated method stub
        if (localName.equalsIgnoreCase("prices")) {
            this.in_prices = true ;
        }else if (localName.equalsIgnoreCase("pricelist")) {
            String attrValue = attributes.getValue("currency");
            if (attrValue.equalsIgnoreCase("usd")){
            this.in_pricelist = true;
        }else if (localName.equalsIgnoreCase("price")){
            String attrValue2 = attributes.getValue("commodity");
            if (attrValue2.equalsIgnoreCase("gold")){
            this.in_uspricegold = true;
        }else if (localName.equalsIgnoreCase("price")){
            String attrValue3 = attributes.getValue("commodity");
            if (attrValue3.equalsIgnoreCase("silver")){
            this.in_uspricesilver = true;
        }
        }}}
    }
     @Override
      public void endElement(String namespaceURI, String localName, String qName)
                    throws SAXException {
             if (localName.equalsIgnoreCase("prices")) {
                 this.in_prices = false;
             }else if (localName.equalsIgnoreCase("pricelist")) {
                 this.in_pricelist = false;
             }else if (localName.equalsIgnoreCase("price")) {
                 this.in_uspricegold = false;
             }else if (localName.equalsIgnoreCase("price")) {
                 this.in_uspricesilver = false;       
             }
     }  

     @Override
     public void characters(char[] ch, int start, int length)throws SAXException {

                    if(this.in_uspricegold) {                       
                    //info.setSpotGold(new String (ch, start, length));                     
                    //} 
                    int spotgold = Integer.parseInt(new String (ch, start, length));                        
                    info.setSpotGold(spotgold);
                    this.in_uspricegold = false;
                    }else{}

                    if(this.in_uspricesilver){                     
                    //info.setSpotSilver(new String(ch, start, length));                      
                    // }    
                    int spotsilver = Integer.parseInt(new String(ch, start, length));                       
                    info.setSpotSilver(spotsilver);
                    this.in_uspricesilver = false;
                    }else{}
            }

    }

Collected Data Set

public class XMLDataCollected{

 private int spotsilver = 0;
 private int spotgold = 0;

    public int getSpotGold() {
    return spotgold;
    }   
    public void setSpotGold(int spotgold){          
    this.spotgold = spotgold;   
    }

    public int getSpotSilver() {
    return spotsilver;
    }           
    public void setSpotSilver(int spotsilver){      
    this.spotsilver = spotsilver;
    }

    public String toString(){
        return  "gold " + spotgold + " silver "+ spotsilver;

    }

}

First of all your method characters has to be much simpler. The only thing that it does is to read the characters between the tags. It will be like this:

public void characters(char[] ch, int start, int end) {
    buffer.append(new String(ch, start, end));
}

As you can see I'm using a StringBuffer as a private field. It's instantiate at the beginning of the startElement method and "resetted" at the beginning of the endElement .

    value = buffer.toString();
    buffer.setLength(0);

The field value will actually keep the real value of the field.

All my class for reference:

private String value;
private StringBuffer buffer;

@Override
public void startElement(
        String nameSpaceURI, 
        String localName, 
        String qName, 
        Attributes atts
        ) {

    buffer = new StringBuffer();

    if(localName.equals("myTag"))
    bean = new Bean();

}

public void endElement(
        String uri, 
        String localName, 
        String qName) {

    value = buffer.toString();
    buffer.setLength(0);

    if(localName.equals("myTag") {
        bean.setSomething(value);
    }

}

public void characters(char[] ch, int start, int end) {
    buffer.append(new String(ch, start, end));
}

Hope this helps. :)

EDIT

Here the code adapted to the op xml. I haven't tried it but SHOULD work. ;)

private String value;
private StringBuffer buffer;

private XMLCOllected info;
private boolean inPriceList;
private boolean inGold;
private boolean inSilver;

@Override
public void startElement(
        String nameSpaceURI,
        String localName,
        String qName,
        Attributes atts
) {

    buffer = new StringBuffer();

    if(localName.equals("prices")) {
        this.info = new XMLCollected();
    } else if(localName.equals("pricelist")) {
        String attr = atts.getValue("currency");
        if(attr.equals("usd")) {
            this.inPriceList = true;
        }
    } else if(localName.equals("price") && inPrices) {
        String attr = atts.getValue("commodity");
        if(attr.equals("gold")) {
            this.inGold = true;
        } else if(attr.equals("silver")) {
            this.inSilver = true;
        }
    }
}

public void endElement(
        String uri,
        String localName,
        String qName) {

    value = buffer.toString();
    buffer.setLength(0);

    if(localName.equals("price") && inGold && inPriceList) {
        this.info.setSpotGold(value);
        this.inGold = false;
    } else if(localName.equals("price") && inSilver && inPriceList) {
        this.info.setSpotSilver(value);
        this.inSilver = false;
    } else if(localName.equals("pricelist")) {
        this.inPriceList = false;
    }
}

public void characters(char[] ch, int start, int end) {
    buffer.append(new String(ch, start, end));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM