2012-07-09 151 views
0

我是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

回答

1

所有方法則首先必須要簡單得多。它唯一要做的就是讀取標籤之間的字符。這將是這樣的:

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