Xml

小明

明明

小红

红红

小亮

亮亮

1.Sax解析

优缺点:解析速度快,占用内存少,但是没需要解析一类不同的xml,就要编写新的适合该类xml处理的类,用起来还是有点麻烦,采用的是流式解析,解析是同步的。

原理:对文档进行扫描,当扫描到文档开始或者结束,标签开始或者结束,或者标签中的特殊属性时就通知事件处理函数,由事件处理函数做相应的动作,然后继续同样的扫描,知道文档结束。

/**

* SAX是一个解析速度快并且占用内存少的xml解析器,SAX解析XML文件采用的是事件驱动,它并不需要解析完整个文档,而是按内容顺序解析文档的过程

*/

public List sax2xml(InputStream is) throws Exception {

SAXParserFactory spf = SAXParserFactory.newInstance();

//初始化Sax解析器

SAXParser sp = spf.newSAXParser();

//新建解析处理器

MyHandler handler = new MyHandler();

//将解析交给处理器

sp.parse(is, handler);

//返回List

return handler.getList();

}

public class MyHandler extends DefaultHandler {

private List list;

private Student student;

//用于存储读取的临时变量

private String tempString;

/**

* 解析到文档开始调用,一般做初始化操作

*

* @throws SAXException

*/

@Override

public void startDocument() throws SAXException {

list = new ArrayList<>();

super.startDocument();

}

/**

* 解析到文档末尾调用,一般做回收操作

*

* @throws SAXException

*/

@Override

public void endDocument() throws SAXException {

super.endDocument();

}

/**

* 每读到一个元素就调用该方法

*

* @param uri

* @param localName

* @param qName

* @param attributes

* @throws SAXException

*/

@Override

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

if ("student".equals(qName)) {

//读到student标签

student = new Student();

} else if ("name".equals(qName)) {

//获取name里面的属性

String sex = attributes.getValue("sex");

student.setSex(sex);

}

super.startElement(uri, localName, qName, attributes);

}

/**

* 读到元素的结尾调用

*

* @param uri

* @param localName

* @param qName

* @throws SAXException

*/

@Override

public void endElement(String uri, String localName, String qName) throws SAXException {

if ("student".equals(qName)) {

list.add(student);

}

if ("name".equals(qName)) {

student.setName(tempString);

} else if ("nickName".equals(qName)) {

student.setNickName(tempString);

}

super.endElement(uri, localName, qName);

}

/**

* 读到属性内容调用

*

* @param ch

* @param start

* @param length

* @throws SAXException

*/

@Override

public void characters(char[] ch, int start, int length) throws SAXException {

tempString = new String(ch, start, length);

super.characters(ch, start, length);

}

/**

* 获取该List

*

* @return

*/

public List getList() {

return list;

}

}

2.Dom解析

优缺点:内存消耗太大,容易OOM,但是写起来比较容易,双层for循环遍历就ok.

原理:先把文档加载到内存中,然后通过DOM API遍历xml树形结构(getElementByTagName,getChildNotes)的方式获取数据

/**

* DOM解析XML文件时,会将XML文件的所有内容读取到内存中(内存的消耗比较大),然后允许您使用DOM API遍历XML树、检索所需的数据

*/

public List dom2xml(InputStream is) throws Exception {

//一系列的初始化

List list = new ArrayList<>();

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();

//获得Document对象

Document document = builder.parse(is);

//获得student的List

NodeList studentList = document.getElementsByTagName("student");

//遍历student标签

for (int i = 0; i < studentList.getLength(); i++) {

//获得student标签

Node node_student = studentList.item(i);

//获得student标签里面的标签

NodeList childNodes = node_student.getChildNodes();

//新建student对象

Student student = new Student();

//遍历student标签里面的标签

for (int j = 0; j < childNodes.getLength(); j++) {

//获得name和nickName标签

Node childNode = childNodes.item(j);

//判断是name还是nickName

if ("name".equals(childNode.getNodeName())) {

String name = childNode.getTextContent();

student.setName(name);

//获取name的属性

NamedNodeMap nnm = childNode.getAttributes();

//获取sex属性,由于只有一个属性,所以取0

Node n = nnm.item(0);

student.setSex(n.getTextContent());

} else if ("nickName".equals(childNode.getNodeName())) {

String nickName = childNode.getTextContent();

student.setNickName(nickName);

}

}

//加到List中

list.add(student);

}

return list;

}

3.Pull解析

pull解析提供了开始开始元素和结束元素,当某个元素开始的时候,我们可以调用parse.nextText 从Xml文档中提取所有的字符数据,当解析到一个文档结束的时候,自动生成EndDocument,和Sax解析类似,可以使用一个switch对感兴趣的事件进行处理,

/**

* Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,可以使用一个switch对感兴趣的事件进行处理

*/

public List pull2xml(InputStream is) throws Exception {

List list = null;

Student student = null;

//创建xmlPull解析器

XmlPullParser parser = Xml.newPullParser();

///初始化xmlPull解析器

parser.setInput(is, "utf-8");

//读取文件的类型

int type = parser.getEventType();

//无限判断文件类型进行读取

while (type != XmlPullParser.END_DOCUMENT) {

switch (type) {

//开始标签

case XmlPullParser.START_TAG:

if ("students".equals(parser.getName())) {

list = new ArrayList<>();

} else if ("student".equals(parser.getName())) {

student = new Student();

} else if ("name".equals(parser.getName())) {

//获取sex属性

String sex = parser.getAttributeValue(null,"sex");

student.setSex(sex);

//获取name值

String name = parser.nextText();

student.setName(name);

} else if ("nickName".equals(parser.getName())) {

//获取nickName值

String nickName = parser.nextText();

student.setNickName(nickName);

}

break;

//结束标签

case XmlPullParser.END_TAG:

if ("student".equals(parser.getName())) {

list.add(student);

}

break;

}

//继续往下读取标签类型

type = parser.next();

}

return list;

}

注意:SAX和Pull的区别:SAX解析器的工作方式是自动将事件推入事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。

一个栗子,在Pull解析中,我可以根据条件选择来决定是否 parser.next()继续往下读取标签或者break跳出循环,结束解析。

c语言中xml的解析方式,浅谈Xml的三种解析方式相关推荐

  1. 浅谈js函数三种定义方式 四种调用方式 调用顺序

    在Javascript定义一个函数一般有如下三种方式: 函数关键字(function)语句: function fnMethodName(x){alert(x);} 函数字面量(Function Li ...

  2. c语言函数三种方式,c语言函数的三种调用方式是什么

    函数的三种调用方式:1.函数作为表达式中的一项出现在表达式中,例"z=max(x,y)":2.函数作为一个单独的语句,例"printf("%d",a) ...

  3. 计算机文件保存方式,Word文档的三种保存方式

    word中有多种保存文档的方式.可保存当前处理的活动文档 (活动文档:正在处理的文档.在 Microsoft word 中键入的文本或插入的图形将出现在活动文档中.活动文档的标题栏是突出显示的.),无 ...

  4. oracle分页的三种方式,oracle 使用rownum的三种分页方式

    rownum是Oracle数据库中的一个特有关键字,返回的是一个数字代表记录的行号. 基础知识:rownum只能做 获取51到100的数据 三种分页的写法: 1.使用minus,原理就是查询出前100 ...

  5. 浅谈CORS的两种请求方式

    先附上HTTP中文开发手册链接:http://www.php.cn/manual/view/35588.html 参考文章:https://blog.csdn.net/qq_34125349/arti ...

  6. 浅谈STM32的三种Boot模式

    文章目录 一.关于BOOT模式的介绍 二.实际例子进行分析 三.分析上电启动流程 四.小结 五.参考资料 一.关于BOOT模式的介绍 所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的 ...

  7. 浅谈STM32的三种Boot模式的差异以及用汇编语言设计一个LED灯程序

    STM32的三种Boot模式的差异 1.三种方式的比较 用汇编程序完成LED的程序 1.三种方式的比较 所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值 ...

  8. 浅谈Floyd的三种用法 By cellur925

    Floyd大家可能第一时间想到的是他求多源最短路的n³算法.其实它还有另外两种算法的嘛qwq.写一发总结好了qwq. 一.多源最短路 放段代码跑,注意枚举顺序,用邻接矩阵存图.本质是一种动规. 复杂度 ...

  9. 用python解析xml的几种方法,Python_XML的三种解析方法

    什么是XML? XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这 ...

  10. python中if brthon环境安装包_Ant、Gradle、Python三种打包方式的介绍

    今天谈一下Androdi三种打包方式,Ant.Gradle.Python. 当然最开始打包用Ant 很方便,后来转Studio开发,自带很多Gradle插件就用了它,然后随着打包数量越多,打包时间成了 ...

最新文章

  1. C++多线程:thread类创建线程的多种方式
  2. elastic job review
  3. 《Linux内核设计与实现》课程学习重点问题总结
  4. Windows系统查看端口占用
  5. ansys 帮助文档_ANSYS 2020 R1版帮助文档简介
  6. JAVA和遮掩_JAVA 你不知道的秘密 覆写,重载,隐藏,遮蔽,遮掩
  7. 计算几何 -- 旋转坐标系
  8. mysql group concat_MySQL 的 GROUP_CONCAT 函数详解
  9. 机器学习——对三种模式的看法
  10. HTTP状态代码列表
  11. 莫烦强化学习-Q Learning
  12. Mac 怎么打开两个终端
  13. 网页设计作业-HTML5+CSS大作业——端午节日(25页) 图片滚动
  14. 基于mysql的报表工具有哪些?值得推荐的mysql报表工具
  15. 向人工盘点库存和物品说再见
  16. mysql免费常用编译器_20款最好的免费的IDES和编辑器
  17. mdio phy(bcm5482)访问
  18. numpy ndarray 与 array
  19. Azure机器学习模型搭建
  20. 迅雷看看看电影,画面是绿色的,不能看

热门文章

  1. 移动开发者必须了解的10大跨平台工具
  2. python numpy 矩阵运算_NumPy向量和矩阵的运算
  3. android怎么防8门神器,八门神器(GameKiller)怎么用?安卓版使用教程
  4. linux连接Redis客户端
  5. 五子棋游戏初次编写尝试
  6. Python常用模块12-python的xlsxwriter模块(操作excel)
  7. 萤石摄像头实现web端监控预览以及录像回放
  8. 十年PHP架构师的成长之路,程序员必备
  9. PDF有口令密码怎么移除?
  10. MySQL5.5安装步骤