如何使用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;
}
}
所有方法则首先必须要简单得多。它唯一要做的就是读取标签之间的字符。这将是这样的:
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));
}
感谢您的回应。不过,我现在实际上有点困惑。忍受着我我是一个小菜鸟。大声笑。在我的情况下,我应该输入行 value = buffer.toString(); 在上面的字符方法中... buffer.append(new String(ch,start,end));? – 2012-07-18 19:58:59
没问题,我没那么有经验!顺便说一句,不要。这是因为字符方法可以多次调用,所以它应该只用于收集标签之间的值。您应该在结束标记中设置值,而不是在字符方法中。你能提供一个你正在解析的XML文件的例子吗(所以我可以用你的bean来改进答案)? – Enrichman 2012-07-18 23:08:57
下面是我试图解析的内容。这是网址。 (http://www.xmlcharts.com/cache/precious-metals.xml)......
请,如果你发现答案有用,你应该接受它。否则,告诉我们什么仍然不起作用,我们将看到如何解决它! :) – Enrichman 2012-07-10 09:16:57