0120 xml解析+SAX
0120 rss解析新闻的标准 xml 解析 可以得到想要的信息 什么是sax 另一种是dom SAX是逐行的解析方式 可以随时停止解析 但是,操作复杂,添加删除费劲
sax全称simple api for xml是一个接口,也是一个软件包 作为接口,有c++ 和java等的实现、sax是以事件为驱动的解析的过程
开始解析一个标签了,会通知一个函数
在实现类中覆盖四个接口的方法 ContentHandler ErrorHandler DTDHandler EntityResolver
对于如下文档 <doc> <para>Hello,world!</para></doc> 在解析过程中会产生如下事件 start document start element:doc start element :para character:Hello,world! end element:para end element:doc end document 我们要做的就是写上产生这些事件的代码 ContentHandler 接口是解析xm的主体
1,创建一个SAXParaseFactory SAXParserFactory factory =SAXPaserfactory.newInstance(); 2,getXMLReader()得到reader xmlReader reader=factory.newSAXParser().getXMLReader(); 3,为XMLReader设置内容处理器 为XMLReader设置内容处理器 reader.setContentReader(new MyContentHandler()); 开始解析文件 reader.parse(new InputSource(new StringReader(ResultStr)));
ContentHandler方法非常多,但是我们又不需要实现这么多方法来复写接口 比如只想实现其中5个方法 采用适配器设计方法(我们使用一个类,里面的方法都实现接口里面的方法,但是都是空方法) 现在只要继承这个DefaultHandler 我们可以只复写其中5个方法,其他的由于已经DefaultHandler已经提供了空方法
StringReader()以流的方式来处理一个字符窜
startElement(String namespaceURI,String localname,Sring qName,Attributes attr) namespaceURI 当前正在解析的标签的命名空间 localname 得到的标签不包含前缀 qname是得到前缀<abc:name> abc就是前缀
获取标签的全部属性 attr.getLocalName(i) 得到第i个属性的名字 attr.getValue(i)得到第i个属性的值
startElement() 开始解析一个标签
一边读取一边解析,适合手机开发
XML_Test.java
1 package com.example.xml_test; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.io.StringReader; 6 7 import javax.xml.parsers.ParserConfigurationException; 8 import javax.xml.parsers.SAXParserFactory; 9 10 import org.xml.sax.InputSource; 11 import org.xml.sax.SAXException; 12 import org.xml.sax.XMLReader; 13 14 import com.example.utils.HttpDownloader; 15 16 import android.os.Bundle; 17 import android.app.Activity; 18 import android.view.Menu; 19 import android.view.View; 20 import android.view.View.OnClickListener; 21 import android.widget.Button; 22 23 public class XML_Test extends Activity { 24 25 private Button parseButton; 26 @Override 27 protected void onCreate(Bundle savedInstanceState) { 28 super.onCreate(savedInstanceState); 29 setContentView(R.layout.activity_xml__test); 30 parseButton=(Button)findViewById(R.id.parseButton); 31 parseButton.setOnClickListener(new ParseButtonListener()); 32 } 33 class ParseButtonListener implements OnClickListener{ 34 35 @Override 36 public void onClick(View v) { 37 // TODO Auto-generated method stub 38 HttpDownloader hd=new HttpDownloader(); 39 40 String resultStr = null; 41 try { 42 resultStr = hd.download("http://192.168.1.107:8081/voa1500/test.xml"); 43 } catch (IOException e1) { 44 // TODO Auto-generated catch block 45 e1.printStackTrace(); 46 } 47 48 try { 49 //创建一个SAXParserFactory 50 SAXParserFactory factory=SAXParserFactory.newInstance(); 51 XMLReader reader=factory.newSAXParser().getXMLReader(); 52 //为XMLReader设置内容处理器 53 reader.setContentHandler(new MyContentHandler()); 54 //开始解析文件 55 reader.parse(new InputSource(new StringReader(resultStr))); 56 } catch (Exception e) { 57 // TODO Auto-generated catch block 58 e.printStackTrace(); 59 } 60 61 62 } 63 64 65 } 66 67 68 69 70 }
MyContentHandler.java
1 package com.example.xml_test; 2 3 import org.xml.sax.Attributes; 4 import org.xml.sax.helpers.DefaultHandler; 5 6 public class MyContentHandler extends DefaultHandler{ 7 /** 8 * ContentHandler方法非常多,但是我们又不需要实现这么多方法来复写接口 9 *比如只想实现其中5个方法 10 *采用适配器设计方法(我们使用一个类,里面的方法都实现接口里面的方法,但是都是空方法) 11 *现在只要继承这个DefaultHandler 12 *我们可以只复写其中5个方法,其他的由于已经DefaultHandler已经提供了空方法 13 */ 14 String tagName,sex,hisname,status,address,money; 15 public void startDocument() 16 { 17 System.out.println("--begin--"); 18 19 } 20 21 public void endDocument() 22 { 23 System.out.println("--end--"); 24 } 25 26 //namespaceURI 当前正在解析的标签的命名空间 localname 得到的标签不包含前缀 27 //qname是得到前缀<abc:name> abc就是前缀 28 //遇到标签开始解析一个标签就会调用此函数,就算开始读取第二个标签比如<name>还是要调用这个函数 29 public void startElement(String namespaceURI, String localName, 30 String qName, Attributes attr) 31 { 32 tagName=localName; 33 if(localName.equals("worker")) 34 { 35 for(int i=0;i<attr.getLength();i++)//getLength();Return the number of attributes in the list. 36 { 37 System.out.println(attr.getLocalName(i)+attr.getValue(i)); 38 } 39 } 40 /** 41 * attr.getLocalName(i) 得到第i个属性的名字 id,name 42 *attr.getValue(i)得到第i个属性的值 123 ,zhangsan 43 *<worker id=123,name="zhangsan"> 44 */ 45 46 } 47 //当一个标签解析完后就会调用此函数 48 public void endElement(String namespaceURI, String localName, String qName) 49 { 50 tagName=""; 51 if(localName.equals("worker"))//到了最后一个标签 52 {this.printout();} 53 54 55 } 56 //字符数组(即标签) ,起始点,结束点 57 //读取标签的内容时候就要调用characters方法<name>zhangsan</name> 读取zhangsan时候就要调用这个 58 public void characters (char[] ch, int start, int length) 59 { 60 //判断来自哪个标签 61 if (tagName.equals("name")) 62 hisname = new String(ch, start, length); 63 else if (tagName.equals("sex")) 64 sex = new String(ch, start, length); 65 else if (tagName.equals("status")) 66 status = new String(ch, start, length); 67 else if (tagName.equals("address")) 68 address = new String(ch, start, length); 69 else if (tagName.equals("money")) 70 money = new String(ch, start, length); 71 72 } 73 74 75 76 77 public void printout() 78 { 79 System.out.print("name: "); 80 System.out.println(hisname); 81 System.out.print("sex: "); 82 System.out.println(sex); 83 System.out.print("status: "); 84 System.out.println(status); 85 System.out.print("address: "); 86 System.out.println(address); 87 System.out.print("money: "); 88 System.out.println(money); 89 System.out.println(); 90 } 91 }