SAX解析方法介绍:

  SAX(Simple API for XML)是一个解析速度快并且占用内存少的XML解析器,非常适合用于Android等移动设备。SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。

Pull解析器:

  Pull解析是一个while循环,随时可以跳出。Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析工作。

DOM解析:

  DOM解析XML文件时,会将XML的所有内容读取到内存中,然后允许您使用DOM API遍历XML树、检索所需的数据。因为DOM需要将所有内容读取到内存中,所以内存的消耗比较大,不建议使用DOM解析XML文件,若文件较小可行。

首先新建一个xml文件,放在res/raw目录下,没有raw目录则新建一个。

要解析的itcase.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="">
<name>liming</name>
<age></age>
</person>
<person id="">
<name>lixiang</name>
<age></age>
</person>
</persons>

新建一个类存放解析的内容

Person.java如下:

 public class Person {
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;
}
}

以上所需要的准备好了,就开始解析xml工作:

首先是SAX解析

新建一个 XMLContentHandler.java文件内容如下:

 public class XMLContentHandler extends DefaultHandler{

     private List<Person> persons = null;
private Person currentPerson;
private String tagName = null;//当前解析的元素标签 public List<Person> getPersons() {
return persons;
} @Override/**【文档开始时,调用此方法】**/
public void startDocument() throws SAXException {
persons = new ArrayList<>();
} @Override/**【标签开始时,调用此方法】**/
/**【uri是命名空间|localName是不带命名空间前缀的标签名|qName是带命名空间前缀的标签名|attributes可以得到所有的属性名和对应的值】**/
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (localName.equals("person")) {
currentPerson = new Person();
currentPerson.setId(Integer.parseInt(attributes.getValue("id")));
}
this.tagName = localName;
} @Override/**【接收标签中字符数据时,调用此方法】**/
/**【ch存放标签中的内容,start是起始位置,length是内容长度】**/
public void characters(char[] ch, int start, int length) throws SAXException {
if (tagName != null) {
String data = new String(ch, start, length);
if (tagName.equals("name")) {
this.currentPerson.setName(data);
} else if (tagName.equals("age")) {
this.currentPerson.setAge(Short.parseShort(data));
}
}
} @Override/**【标签结束时,调用此方法】**/
/**【localName表示元素本地名称(不带前缀),qName表示元素的限定名(带前缀)】**/
public void endElement(String uri, String localName, String qName) throws SAXException {
if (localName.equals("person")) {
persons.add(currentPerson);
currentPerson = null;
}
this.tagName = null;
} }

新建一个调用XMLContentHandler中方法的XMLParsingMethods.java类,内容如下:

 public class XMLParsingMethods {

     /**【SAX解析XML文件】**/
public static List<Person> readXmlBySAX(InputStream inputStream) {
try {
/**【创建解析器】**/
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
XMLContentHandler handler = new XMLContentHandler();
saxParser.parse(inputStream, handler);
inputStream.close();
return handler.getPersons();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

到这里,SAX解析XML文件工作已经完成了,调用XMLPersingMethods中的readXmlBySAX就可以解析itcase.xml文件。在这里就先不调用,把三种的解析方法讲完再一并调用。

DOM解析XML文件:直接在XMLPersingMethods中添加解析方法

 public class XMLParsingMethods {

     /**【SAX解析XML文件】**/
public static List<Person> readXmlBySAX(InputStream inputStream) {
......
} /**【DOM解析XML文件】**/
public static List<Person> readXmlByDOM(InputStream inputStream){
List<Person> persons = new ArrayList<>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(inputStream); Element root = dom.getDocumentElement();
/**【查找所有person节点】**/
NodeList items = root.getElementsByTagName("person");
for (int i = ; i < items.getLength(); i++) {
Person person = new Person(); /**【得到第一个person的节点】**/
Element personNode = (Element) items.item(i); /**【获取person节点的id属性】**/
person.setId(new Integer(personNode.getAttribute("id"))); /**【获取person节点下的所有子节点(标签之间的空白节点和name/age节点)】**/
NodeList childsNodes = personNode.getChildNodes(); /**【遍历所有子节点】**/
for (int j = ; j < childsNodes.getLength(); j++) {
Node node = (Node) childsNodes.item(j); /**【判断是否为元素类型】**/
if(node.getNodeType() == Node.ELEMENT_NODE){
Element childNode = (Element) node;
/**【判断是否是name元素】**/
if ("name".equals(childNode.getNodeName())) {
/**【获取name元素下的text节点,然后从text节点获取数据】**/
person.setName(childNode.getFirstChild().getNodeValue());
/**【判断是否是age元素】**/
}else if("age".equals(childNode.getNodeName())){
/**【获取age元素下的text节点,然后从text节点获取数据】**/
person.setAge(new Short(childNode.getFirstChild().getNodeValue()));
}
}
}
persons.add(person);
}
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return persons;
}
}

至此,DOM解析XML文件工作也已经完成了。

Pull解析器解析XML文件:

 public class XMLParsingMethods {

     /**【SAX解析XML文件】**/
public static List<Person> readXmlBySAX(InputStream inputStream) {
......
} /**【DOM解析XML文件】**/
public static List<Person> readXmlByDOM(InputStream inputStream){
......
} /**【Pull解析器解析XML文件】**/
public static List<Person> readXmlByPull(InputStream inputStream){
XmlPullParser parser = Xml.newPullParser();
try {
parser.setInput(inputStream,"UTF-8");
int eventType = parser.getEventType(); Person currenPerson = null;
List<Person> persons = null; while(eventType != XmlPullParser.END_DOCUMENT){
switch (eventType){
case XmlPullParser.START_DOCUMENT:/**【文档开始事件】**/
persons = new ArrayList<>();
break;
case XmlPullParser.START_TAG:/**【元素(即标签)开始事件】**/
String name = parser.getName();
if(name.equals("person")){
currenPerson = new Person();
currenPerson.setId(new Integer(parser.getAttributeValue(null,"id")));
}else if(currenPerson !=null){
if(name.equals("name")){/**【判断标签名(元素名)是否为name】**/
currenPerson.setName(parser.nextText());/**【如果后面是text元素,即返回它的值】**/
}else if(name.equals("age")){
currenPerson.setAge(new Integer(parser.nextText()));
}
}
break;
case XmlPullParser.END_TAG:/**【元素结束事件】**/
if(parser.getName().equalsIgnoreCase("person") && currenPerson != null){
persons.add(currenPerson);
currenPerson = null;
}
break;
}
eventType = parser.next();
}
inputStream.close();
return persons;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

至此,SAX、DOM、Pull三种解析XML文件准备好了,接下来分别调用方法:

布局文件:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:orientation="vertical"
tools:context="com.hs.example.exampleapplication.PersonXML"> <TextView
android:id="@+id/data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="Xml数据:"/> <Button
android:id="@+id/btn_read"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:text="解析XML文件"/> </LinearLayout>

方法调用:

 public class PersonXML extends AppCompatActivity implements View.OnClickListener{

     Button btn_read;
TextView data ;
List<Person> personList = null;
InputStream inputStream; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_personxml); btn_read = this.findViewById(R.id.btn_read);
btn_read.setOnClickListener(this); data = this.findViewById(R.id.data); personList = new ArrayList<>();
} @Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_read:
String result = "";
inputStream = getResources().openRawResource(R.raw.itcase);
if(inputStream == null){
Toast.makeText(this,"InputStream is null",Toast.LENGTH_SHORT).show();
}else{
personList = XMLParsingMethods.readXmlByPull(inputStream); //调用Pull
//personList = XMLParsingMethods.readXmlBySAX(inputStream);//调用SAX
//personList = XMLParsingMethods.readXmlByDOM(inputStream);//调用DOM
if(personList!=null){
for(int i = ;i <personList.size();i++){
String message = "id = " + personList.get(i).getId() + " , name = " + personList.get(i).getName()
+ " , age = " + personList.get(i).getAge() + ".\n";
result += message;
}
}else{
Toast.makeText(this,"persons is null",Toast.LENGTH_SHORT).show();
}
data.setText(result);
XMLParsingMethods.createXmlFile(personList);//这里是接下来使用Pull解析器生成XML文件的方法调用
}
break;
} }
}

运行效果:

顺道讲下使用Pull解析器生成XML文件:

 public class XMLParsingMethods {

     /**【SAX解析XML文件】**/
public static List<Person> readXmlBySAX(InputStream inputStream) {
......
} /**【DOM解析XML文件】**/
public static List<Person> readXmlByDOM(InputStream inputStream){
......
} /**【Pull解析器解析XML文件】**/
public static List<Person> readXmlByPull(InputStream inputStream){
......
} /**【使用Pull解析器生成XML文件内容】**/
public static String WriteXML(List<Person> persons,Writer writer ){
XmlSerializer serializer = Xml.newSerializer();
try {
serializer.setOutput(writer);
serializer.startDocument("UTF-8",true); /**【第一个参数为命名空间,不使用命名空间可以设置为null】**/
serializer.startTag("","persons");
/**【XML文件中要生成的内容】**/
for(Person person : persons){
serializer.startTag("","person");
serializer.attribute("", "id", String.valueOf(person.getId()) ); serializer.startTag("","name");
serializer.text(person.getName());
serializer.endTag("","name"); serializer.startTag("","age");
serializer.text(String.valueOf(person.getAge()));
serializer.endTag("","age"); serializer.endTag("","person");
}
serializer.endTag("","persons");
serializer.endDocument();
return writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /**【生成XML文件代码】**/
public static void createXmlFile(List<Person> persons){
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
try {
File sdCard = Environment.getExternalStorageDirectory();
File xmlFile = new File(sdCard + File.separator + "testFolder/" + "myitcast.xml");
FileOutputStream outStream = new FileOutputStream(xmlFile);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outStream , "UTF-8");
BufferedWriter writerFile = new BufferedWriter(outputStreamWriter); WriteXML(persons,writerFile);
writerFile.flush();
writerFile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

运行后:

新建文件要先获得文件操作系统权限,推荐文章:https://blog.csdn.net/weixin_44001878/article/details/89520246

以上内容参考于:https://www.open-open.com/lib/view/open1392780226397.html

Android-----解析xml文件的三种方式的更多相关文章

  1. 解析Xml文件的三种方式及其特点

    解析Xml文件的三种方式 1.Sax解析(simple api  for xml) 使用流式处理的方式,它并不记录所读内容的相关信息.它是一种以事件为驱动的XML API,解析速度快,占用内存少.使用 ...

  2. 解析Xml文件的三种方式

    1.Sax解析(simple api  for xml) 使用流式处理的方式,它并不记录所读内容的相关信息.它是一种以事件为驱动的XML API,解析速度快,占用内存少.使用回调函数来实现. clas ...

  3. 解析xml文件的四种方式

    什么是 XML? XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML 标签没 ...

  4. 解析XML文件的几种方式及其比较

    解析xml文件目前比较流行的主要有四种方式: 1. DOM(Document Object Model)它把整个XML文档当成一个对象加载到内  存,不管文档有多大.它一般处理小文件 2.SAX(Si ...

  5. android中解析文件的三种方式

    android中解析文件的三种方式     好久没有动手写点东西了,最近在研究android的相关技术,现在就android中解析文件的三种方式做以下总结.其主要有:SAX(Simple API fo ...

  6. android解析xml文件的方式

    android解析xml文件的方式   作者:东子哥 ,发布于2012-11-26,来源:博客园   在androd手机中处理xml数据时很常见的事情,通常在不同平台传输数据的时候,我们就可能使用xm ...

  7. 解析XML文件的几种常见操作方法—DOM/SAX/DOM4j

    解析XML文件的几种常见操作方法—DOM/SAX/DOM4j 一直想学点什么东西,有些浮躁,努力使自己静下心来看点东西,哪怕是回顾一下知识.看到了xml解析,目前我还没用到过.但多了解一下,加深点记忆 ...

  8. java读取XML文件的四种方式

    java读取XML文件的四种方式 Xml代码 <?xml version="1.0" encoding="GB2312"?> <RESULT& ...

  9. Velocity中加载vm文件的三种方式

    Velocity中加载vm文件的三种方式: a.  加载classpath目录下的vm文件 /** * 初始化Velocity引擎 * --VelocityEngine是单例模式,线程安全 * @th ...

随机推荐

  1. uniform

    float timeValue = glfwGetTime(); float greenValue = (sin(timeValue) / 2.0f) + 0.5f; int vertexColorL ...

  2. ESA2GJK1DH1K升级篇: 升级STM32 预热: 单片机定时 使用 http 获取云端文本文件里面的内容,然后显示在液晶屏

    前言: 实现功能概要 STM32使用AT指令控制Wi-Fi以TCP方式连接咱上节安装的Web服务器,然后使用http的get协议获取云端文本文件里面的内容, 然后把获取的数据显示在OLED液晶屏.   ...

  3. [RN] React Native 自定义导航栏随滚动渐变

    React Native 自定义导航栏随滚动渐变 实现效果预览: 代码实现: 1.定义导航栏 NavPage.js import React, {Component} from 'react'; im ...

  4. IE和火狐的事件机制有什么区别

    1.IE的事件流是冒泡流,火狐支持冒泡流和捕获流. 2.阻止事件冒泡:IE---e.cancelBubble = true;    火狐---e.stopPropagation();

  5. js中的new操作符解析

    new 操作符做了以下事情: 1.创建一个对象,将对象赋值给this function Person(name, age) { console.log(this) //Person {} } let ...

  6. ES6-Generator使用与改写

    用Generator封装Symbol中的iterator方法: 注意:Generator的function后必须写* config:分别有3个txt文件,两个文件写路径,一个文件写要输出的内容 前置写 ...

  7. GDAL在VS下配置测试

    刚才在VS2013里面配置了一下GDAL,然后就测试了配置成功与否.熟料,竟然发现在微软的Visual Studio 2013版本中,调用MessageBox()这个函数的时候报错了. 错误信息如下 ...

  8. 2018-2019-2 网络对抗技术 20165230 Exp7 网络欺诈防范

    实验目的 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法. 实验内容 简单应用SET工具建立冒名网站 ettercap DNS spoof 结合应用两种技术,用DNS sp ...

  9. Java四则运算——图形化界面

    一.前提 (1)作业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2213 (2)GitHub地址:https://github ...

  10. [C++进阶] 数据结构与算法

    1 出栈&入栈问题 一个栈的入栈序列为ABCDE,则不可能的出栈序列为?(不定项选择题) A:ECDBA  B:DCEAB   C:DECBA   D:ABCDE   E:EDCBA 正确答案 ...