如何使用SAX解析器解析android中的xml?

问题描述:

我是android的noob,我试图学习如何用SAX解析器解析xml。我写了一个测试应用程序来尝试实现它,但我似乎无法使其工作。我想我的文本视图显示来自XML的相应值,但它不工作。谁能帮忙?如何使用SAX解析器解析android中的xml?

分析器

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

内容处理器

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

    } 

收集的数据集

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; 

    } 

} 
+0

请,如果你发现答案有用,你应该接受它。否则,告诉我们什么仍然不起作用,我们将看到如何解决它! :) – Enrichman 2012-07-10 09:16:57

所有方法则首先必须要简单得多。它唯一要做的就是读取标签之间的字符。这将是这样的:

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

正如你可以看到我使用一个StringBuffer作为一个私有字段。它在startElement方法的开始处实例化,并在endElement的开始处“重置”。

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

领域实际上将保持该领域的真正价值。

所有我的标准类别:

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

希望这有助于。 :)

EDIT

这里适于运算XML代码。我没有尝试过,但应该工作。 ;)

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)); 
} 
+0

感谢您的回应。不过,我现在实际上有点困惑。忍受着我我是一个小菜鸟。大声笑。在我的情况下,我应该输入行 value = buffer.toString(); 在上面的字符方法中... buffer.append(new String(ch,start,end));? – 2012-07-18 19:58:59

+0

没问题,我没那么有经验!顺便说一句,不要。这是因为字符方法可以多次调用,所以它应该只用于收集标签之间的值。您应该在结束标记中设置值,而不是在字符方法中。你能提供一个你正在解析的XML文件的例子吗(所以我可以用你的bean来改进答案)? – Enrichman 2012-07-18 23:08:57

+0

下面是我试图解析的内容。这是网址。 (http://www.xmlcharts.com/cache/precious-metals.xml)...... 1572.58 575.00 1405.50 27。23 2012-07-18 23:16:24