SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。 SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。下面是一些ContentHandler接口常用的方法:
startDocument():当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。
endDocument():和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。
startElement(String namespaceURI, String localName, String qName, Attributes atts) :当读到一个开始标签的时候,会触发这个方法。namespaceURI就是命名空间,localName是不带命名空间前缀的标签名,qName是带命名空间前缀的标签名。通过atts可以得到所有的属性名和相应的值。要注意的是SAX中一个重要的特点就是它的流式处理,当遇到一个标签的时候,它并不会纪录下以前所碰到的标签,也就是说,在startElement()方法中,所有你所知道的信息,就是标签的名字和属性,至于标签的嵌套结构,上层标签的名字,是否有子元属等等其它与结构相关的信息,都是不得而知的,都需要你的程序来完成。这使得SAX在编程处理上没有DOM来得那么方便。
endElement(String uri, String localName, String name):这个方法和上面的方法相对应,在遇到结束标签的时候,调用这个方法。
characters(char[] ch, int start, int length) :这个方法用来处理在XML文件中读到的内容,第一个参数为文件的字符串内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容。
示例代码:
MainActivity.java
package cn.lixyz.xmltest.activity; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import cn.lixyz.xmltest.R; import cn.lixyz.xmltest.model.Student; import cn.lixyz.xmltest.parser.DOMForXML; import cn.lixyz.xmltest.parser.PULLForXML; import cn.lixyz.xmltest.parser.SAXForXML; public class MainActivity extends Activity { private Button bt_readxml_dom, bt_writexml_dom, bt_writexml_sax, bt_readxml_sax, bt_readxml_pull, bt_writexml_pull; private List<Student> list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findView(); } private void findView() { bt_readxml_dom = (Button) findViewById(R.id.bt_readxml_dom); bt_writexml_dom = (Button) findViewById(R.id.bt_writexml_dom); bt_writexml_sax = (Button) findViewById(R.id.bt_writexml_sax); bt_readxml_sax = (Button) findViewById(R.id.bt_readxml_sax); bt_readxml_pull = (Button) findViewById(R.id.bt_readxml_pull); bt_writexml_pull = (Button) findViewById(R.id.bt_writexml_pull); } public void clickButton(View view) { DOMForXML domForXML; SAXForXML saxForXML; PULLForXML pullForXML; switch (view.getId()) { case R.id.bt_readxml_dom: domForXML = new DOMForXML(); domForXML.domReadXML(); break; case R.id.bt_writexml_dom: domForXML = new DOMForXML(); domForXML.domWriterXML(); break; case R.id.bt_readxml_sax: saxForXML = new SAXForXML(); saxForXML.saxReaderXML(); break; case R.id.bt_writexml_sax: saxForXML = new SAXForXML(); saxForXML.saxWriterXML(); break; case R.id.bt_writexml_pull: pullForXML = new PULLForXML(); pullForXML.pullWriterXML(); break; case R.id.bt_readxml_pull: pullForXML = new PULLForXML(); pullForXML.pullReaderXML(); break; } } }
activity_main.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="cn.lixyz.xmltest.activity.MainActivity" > <Button android:id="@+id/bt_writexml_dom" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="clickButton" android:text="DOM方式生成XML" /> <Button android:id="@+id/bt_readxml_dom" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="clickButton" android:text="DOM方式读取XML" /> <Button android:id="@+id/bt_writexml_sax" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="clickButton" android:text="SAX方式生成XML" /> <Button android:id="@+id/bt_readxml_sax" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="clickButton" android:text="SAX方式读取XML" /> <Button android:id="@+id/bt_writexml_pull" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="clickButton" android:text="PULL生成XML" /> <Button android:id="@+id/bt_readxml_pull" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="clickButton" android:text="PULL解析XML" /> </LinearLayout> </ScrollView>
SAXForXML.java
package cn.lixyz.xmltest.parser; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import android.util.Log; import cn.lixyz.xmltest.model.Student; public class SAXForXML { public void saxWriterXML() { try { // 数据源 List<Student> listData = createStudents(); SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); TransformerHandler transformerHandler = saxTransformerFactory.newTransformerHandler(); // 设置xml属性 Transformer transformer = transformerHandler.getTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 是否缩进 transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8"); // 字符集 transformer.setOutputProperty(OutputKeys.VERSION, "1.0"); // 版本号 File fileFolder = new File("data/data/cn.lixyz.xmltest/files"); if (!fileFolder.exists()) { fileFolder.mkdir(); Log.d("TTTT", "文件夹不存在,已经创建"); } FileOutputStream fileOutputStream = new FileOutputStream( new File("data/data/cn.lixyz.xmltest/files/studentsForSAX.xml")); transformerHandler.setResult(new StreamResult(fileOutputStream)); transformerHandler.startDocument(); AttributesImpl attributesImpl = new AttributesImpl(); attributesImpl.clear(); transformerHandler.startElement("", "", "students", attributesImpl); for (Student student : listData) { attributesImpl.clear(); attributesImpl.addAttribute("", "", "id", "", student.getId() + ""); transformerHandler.startElement("", "", "student", attributesImpl); attributesImpl.clear(); transformerHandler.startElement("", "", "name", attributesImpl); transformerHandler.characters(student.getName().toCharArray(), 0, student.getName().length()); ; transformerHandler.endElement("", "", "name"); attributesImpl.clear(); transformerHandler.startElement("", "", "age", attributesImpl); transformerHandler.characters((student.getAge() + "").toCharArray(), 0, student.getName().length()); ; transformerHandler.endElement("", "", "age"); transformerHandler.endElement("", "", "student"); } transformerHandler.endElement("", "", "students"); transformerHandler.endDocument(); } catch (TransformerConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void saxReaderXML() { try { SAXStudentService studentService = new SAXStudentService(); // InputStream inputStream = // this.getClass().getClassLoader().getResourceAsStream("person.xml"); FileInputStream fileInputStream = new FileInputStream( new File("data/data/cn.lixyz.xmltest/files/studentsForSAX.xml")); List<Student> students = studentService.getStudents(fileInputStream); for (Student student : students) { Log.d("TTTT", "id=" + student.getId() + ",name=" + student.getName() + ",age=" + student.getAge()); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 模拟生成xml的数据 private List<Student> createStudents() { List<Student> listData = new ArrayList<Student>(); listData = new ArrayList<Student>(); Student s1 = new Student(); s1.setId(11); s1.setName("张三"); s1.setAge(10); listData.add(s1); Student s2 = new Student(); s2.setId(22); s2.setName("李四"); s2.setAge(11); listData.add(s2); Student s3 = new Student(); s3.setId(33); s3.setName("王五"); s3.setAge(12); listData.add(s3); Student s4 = new Student(); s4.setId(44); s4.setName("赵六"); s4.setAge(13); listData.add(s4); Student s5 = new Student(); s5.setId(55); s5.setName("刘七"); s5.setAge(14); listData.add(s5); return listData; } }
Student.java
package cn.lixyz.xmltest.model; public class Student { private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
SAXStudentService.java
package cn.lixyz.xmltest.parser; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import android.util.Log; import cn.lixyz.xmltest.model.Student; public class SAXStudentService { public List<Student> getStudents(InputStream inputStream) throws Throwable { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); StudentHandler studentHandel = new StudentHandler(); parser.parse(inputStream, studentHandel); return studentHandel.getStudent(); } class StudentHandler extends DefaultHandler { private List<Student> dataList; private String tag; private Student student; public List<Student> getStudent() { return dataList; } @Override public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub // super.characters(ch, start, length); if (tag != null) { Log.d("TTTT", "~~~~~~~"); String str = new String(ch, start, length); if ("name".equals(tag)) { student.setName(str); } else if ("age".equals(tag)) { student.setAge(Integer.parseInt(str)); } } } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // TODO Auto-generated method stub // super.startElement(uri, localName, qName, attributes); if ("student".equals(localName)) { student = new Student(); Integer id = new Integer(attributes.getValue(0)); student.setId(id); } tag = localName; } @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub // super.startDocument(); dataList = new ArrayList<Student>(); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub // super.endElement(uri, localName, qName); if ("student".equals(localName)) { dataList.add(student); student = null; } tag = null; } } }
来源:https://www.cnblogs.com/xs104/p/4924755.html