- XML 解析 总结 DOM SAX PULL MD
我的GitHub | 我的博客 | 我的微信 | 我的邮箱 |
---|---|---|---|
baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
目录
XML 解析 总结 DOM SAX PULL MD
JDOM 仓库地址
DOM4j 仓库地址
XmlPull 仓库地址
Android 中默认已经引入 XmlPull,如果需要自己引入,需要同时添加以下两个jar包:
几种解析方式简介
- DOM 方式解析:将xml文件全部载入到内存,组装成一棵dom树,然后通过节点以及节点之间的关系来解析xml文件;理解较简单,但是由于整个文档都需要载入内存,不适用于文档较大时。
- SAX 方式解析:基于事件驱动,逐条解析,适用于只处理xml数据;不易编码,而且很难同时访问同一个文档中的多处不同数据。
- JDOM 方式解析:主要用来弥补 DOM 和 SAX 在实际应用当中的不足,比使用 DOM 实现更快,仅使用具体类而不使用接口,因此简化了API,并且易于使用。
- DOM4j 方式解析:JDOM的一种智能分支,功能较强大,建议熟练使用。
- Pull 方式解析:Android提供的一种解析方式,与 SAX 解析器相似,基于事件驱动逐条解析,但需要使用
parser.next()
方法来提取它们。
Pull 解析和 Sax 解析比较
- Pull 解析和 Sax 解析在运行方式上具有相似性,Pull 解析器也提供了类似 SAX 的事件,开始文档
START_DOCUMENT
和结束文档END_DOCUMENT
,开始元素START_TAG
和结束元素END_TAG
等,但需要调用next()
方法提取它们(主动提取事件)。 - SAX 解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。这是他们主要的区别。
- 即:SAX 解析会对整个文档进行解析,而 Pull 解析可以在程序中控制解析到哪里就可以中途停止。
要解析的内容
<?xml version="1.0" encoding="utf-8"?>
<class>
<string name="user">包青天</string>
<string name="job" id="10086">Android开发</string>
<student id="10010">
<string name="user">白乾涛</string>
<string name="job" id="100">码农</string>
</student>
</class>
DOM 解析
代码
public static void domParseXml(String path) throws Exception {
System.out.println("-------------------- DOM解析 --------------------");
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(path);
NodeList stringList = document.getElementsByTagName("string");
domParseNode(stringList); //长度为4【user:包青天, null】【job:Android开发, 10086】【user:白乾涛, null】【job:码农, 100】
NodeList studentList = document.getElementsByTagName("student");
System.out.println("【" + studentList.getLength() + "】");
for (int i = 0; i < studentList.getLength(); i++) {
NamedNodeMap map = studentList.item(i).getAttributes();
String id = map != null && map.getNamedItem("id") != null ? map.getNamedItem("id").getNodeValue() : null;
System.out.println("id = " + id);
NodeList childNodeList = studentList.item(i).getChildNodes();
domParseNode(childNodeList); //长度为5(而不是2)【user:白乾涛, null】【job:码农, 100】
}
}
private static void domParseNode(@NotNull NodeList nodeList) {
System.out.println("【" + nodeList.getLength() + "】");
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i); //获取第i个节点
if (node != null && node.getFirstChild() != null) {
NamedNodeMap map = node.getAttributes(); //获取此节点的所有属性
if (map != null) {
Node nameNode = map.getNamedItem("name"); //获取名为name的属性
String nameNodeValue = nameNode != null ? nameNode.getNodeValue() : null; //获取属性的属性值,也可以使用getTextContent
String nodeValue = node.getFirstChild().getNodeValue(); //获取节点的值
Node idNode = map.getNamedItem("id"); //获取名为id的属性
String idNodeValue = idNode != null ? idNode.getNodeValue() : null;
System.out.println(nameNodeValue + ":" + nodeValue + ", " + idNodeValue);
}
}
}
}
输出
-------------------- DOM 解析 --------------------
【4】
user:包青天, null
job:Android开发, 10086
user:白乾涛, null
job:码农, 100
【1】
id = 10010
【5】
user:白乾涛, null
job:码农, 100
SAX 解析
代码
System.out.println("-------------------- SAX解析 --------------------");
SAXParserFactory.newInstance().newSAXParser().parse(path, new SAXParseHandel());
SAXParseHandel
public class SAXParseHandel extends DefaultHandler {
@Override
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("开始解析");
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("结束解析");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
//开始解析节点时调用此方法
System.out.println("开始解析" + qName);
for (int i = 0; i < attributes.getLength(); i++) {
System.out.println(" " + attributes.getQName(i) + ":" + attributes.getValue(i));//此案例中:getLocalName和getQName一致 ,getType的值为CDATA
}
switch (qName) {
case "student":
int index = attributes.getIndex("id");//当节点名为student时,获取student的id属性
System.out.println(" --" + attributes.getQName(index) + ":" + attributes.getValue(index));
break;
case "string":
System.out.print(" -" + attributes.getValue(attributes.getIndex("name")) + ":");
break;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
//节点解析完毕时调用此方法
System.out.println("结束解析" + qName);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
//此方法用来获取节点的值
String value = new String(ch, start, length).trim();
if (!value.equals("")) {
System.out.println(value);
}
}
}
输出
-------------------- SAX 解析 --------------------
开始解析
开始解析class
开始解析string
name:user
-user:包青天
结束解析string
开始解析string
name:job
id:10086
-job:Android开发
结束解析string
开始解析student
id:10010
--id:10010
开始解析string
name:user
-user:白乾涛
结束解析string
开始解析string
name:job
id:100
-job:码农
结束解析string
结束解析student
结束解析class
结束解析
JDOM 解析
代码
public static void jdomParseXml(String path) throws Exception {
System.out.println("-------------------- JDOM解析 --------------------");
org.jdom2.Document document = new SAXBuilder().build(path);
List<org.jdom2.Element> elementList = document.getRootElement().getChildren();
for (org.jdom2.Element element : elementList) {
jdomParseNode(element);
//解析子节点
for (org.jdom2.Element chileElement : element.getChildren()) {
jdomParseNode(chileElement);
}
}
}
private static void jdomParseNode(@NotNull org.jdom2.Element element) {
System.out.println(element.getName() + ":" + element.getTextTrim());
//解析属性
List<org.jdom2.Attribute> attributeList = element.getAttributes();
for (org.jdom2.Attribute attribute : attributeList) {
System.out.println(" " + attribute.getName() + ":" + attribute.getValue());
}
}
输出
-------------------- JDOM 解析 --------------------
string:包青天
name:user
string:Android开发
name:job
id:10086
student:
id:10010
string:白乾涛
name:user
string:码农
name:job
id:100
DOM4J 解析
代码
public static void dom4JParseXml(String path) throws Exception {
System.out.println("-------------------- DOM4J解析 --------------------");
org.dom4j.Document document = new SAXReader().read(path);
Iterator iterator = document.getRootElement().elementIterator();
while (iterator.hasNext()) {
org.dom4j.Element element = (org.dom4j.Element) iterator.next();
dom4JParseNode(element);
//遍历子节点
Iterator childIterator = element.elementIterator();
while (childIterator.hasNext()) {
dom4JParseNode((org.dom4j.Element) childIterator.next());
}
}
}
private static void dom4JParseNode(@NotNull org.dom4j.Element element) {
System.out.println(element.getName() + ":" + element.getTextTrim());
//解析属性
for (Object object : element.attributes()) {
org.dom4j.Attribute attribute = (org.dom4j.Attribute) object;
System.out.println(" " + attribute.getName() + ":" + attribute.getValue());
}
}
输出
-------------------- DOM4J 解析 --------------------
string:包青天
name:user
string:Android开发
name:job
id:10086
student:
id:10010
string:白乾涛
name:user
string:码农
name:job
id:100
PULL 解析
代码
public static void pullParseXml(String path) throws Exception {
System.out.println("-------------------- PULL解析 --------------------");
InputStream inputStream = new FileInputStream(path);
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(inputStream, "UTF-8");
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) { //文档结束
switch (eventType) {
case XmlPullParser.START_TAG://开始标签
String name = parser.getName();
System.out.println("开始解析 " + name + ", 行列:" + parser.getLineNumber() + "-" + parser.getColumnNumber() + ", 深度:" + parser.getDepth());
for (int i = 0; i < parser.getAttributeCount(); i++) {
//getAttributeType为【CDATA】,getAttributePrefix为【null】,getAttributeNamespace为空【】
System.out.println(" " + parser.getAttributeName(i) + ":" + parser.getAttributeValue(i));//属性名及属性值
}
if ("string".equals(name)) {
System.out.println(parser.nextText()); //获取节点的值
}
break;
case XmlPullParser.END_TAG://结束标签
System.out.println("结束解析" + parser.getName());
break;
}
eventType = parser.next();//这一步很重要,该方法返回一个事件码,也是触发下一个事件的方法
}
}
输出
-------------------- PULL 解析 --------------------
开始解析 class, 行列:2-8, 深度:1
开始解析 string, 行列:3-23, 深度:2
name:user
包青天
开始解析 string, 行列:4-33, 深度:2
name:job
id:10086
Android开发
开始解析 student, 行列:5-23, 深度:2
id:10010
开始解析 string, 行列:6-25, 深度:3
name:user
白乾涛
开始解析 string, 行列:7-33, 深度:3
name:job
id:100
码农
结束解析student
结束解析class
2019-11-23
- XML 解析 总结 DOM SAX PULL MD的更多相关文章
- Android 通过Dom, Sax, Pull解析网络xml数据
这篇文章不是完全原创,XML解析的部分参考了 liuhe688 的文章.文章地址:http://blog.csdn.net/liuhe688/article/details/6415593 这是一个几 ...
- xml解析中的sax解析
title: xml解析中的sax解析 tags: grammar_cjkRuby: true --- SAXPasser 类: parser(File file, DefaultHandler ha ...
- 解析XML:DOM,SAX,PULL
Android解析XML有三种方式:DOM(document object model).SAX(simple api XML).PULL 1.DOM DOM解析XML文件时,会将XML文件的所有内容 ...
- XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax
本文主要涉及:xml概念描述,xml的约束文件,dtd,xsd文件的定义使用,如何在xml中引用xsd文件,如何使用java解析xml,解析xml方式dom sax,dom4j解析xml文件 XML来 ...
- XML解析之DOM详解及与SAX解析方法的比较
XML解析(DOM) XML文件解析方法介绍 我们所用到的NSXMLParser是采用SAX方法解析 SAX(Simple API for XML) 只能读,不能修改,只能顺序访问,适合解析大型XML ...
- Java解析XML汇总(DOM/SAX/JDOM/DOM4j/XPath)
[目录] 一.[基础知识——扫盲] 二.[DOM.SAX.JDOM.DOM4j简单使用介绍] 三.[性能测试] 四.[对比] 五.[小插曲XPath] 六.[补充] 关键字:Java解析xml.解析x ...
- IOS中的XML解析之DOM和SAX
一.介绍 dom是w3c指定的一套规范标准,核心是按树形结构处理数据,dom解析器读入xml文件并在内存中建立一个结构一模一样的“树”,这树各节点和xml各标记对应,通过操纵此“树”来处理xml中的文 ...
- java xml解析方式(DOM、SAX、JDOM、DOM4J)
XML值可扩展标记语言,是用来传输和存储数据的. XMl的特定: XMl文档必须包含根元素.该元素是所有其他元素的父元素.XML文档中的元素形成了一颗文档树,树中的每个元素都可存在子元素. 所有XML ...
- XML解析(一) DOM解析
XML解析技术主要有三种: (1)DOM(Document Object Model)文档对象模型:是 W3C 组织推荐的解析XML 的一种方式,即官方的XML解析技术. (2)SAX(Simple ...
随机推荐
- 深入理解MDL元数据锁
前言: 当你在MySQL中执行一条SQL时,语句并没有在你预期的时间内执行完成,这时候我们通常会登陆到MySQL数据库上查看是不是出了什么问题,通常会使用的一个命令就是 show processli ...
- AIX系统逻辑卷管理
前言: 前期项目需要部署多套AIX环境下RAC集群,之前很少接触AIX系统,上来被创建逻辑卷等基本命令打脸了,其实网上搜下资料很多,总结一下,也是方便自己日后查阅. 创建逻辑卷 1.查看所有磁盘设备 ...
- windows打印机服务自动关闭解决方案
先点击右键点属性,启动方式选自动,然后(1)删除 C:\WINDOWS\system32\spool\PRINTERS 目录下的所有文件.(2)删除注册表 \HKEY_LOCAL_MACHINE\SY ...
- Jenkins+SVN+Ant在Linux环境下自动完成版本的增量更新与编译
第一步:查看安装的jdk版本,查看是否安装ant,查看是否安装Jenkins java -version ant -version rpm -qa|grep jenkins 第二步:安装ant 官网: ...
- LOJ 3159: 「NOI2019」弹跳
题目传送门:LOJ #3159. 题意简述: 二维平面上有 \(n\) 个整点,给定每个整点的坐标 \((x_i,y_i)\). 有 \(m\) 种边,第 \(i\) 种边从 \(p_i\) 号点连向 ...
- 20180610模拟赛T1——脱离地牢
Description 在一个神秘的国度里,年轻的王子Paris与美丽的公主Helen在一起过着幸福的生活.他们都随身带有一块带磁性的阴阳魔法石,身居地狱的魔王Satan早就想着得到这两块石头了,只要 ...
- JAVA web 框架集合
“框架”犹如滔滔江水连绵不绝, 知道有它就好,先掌握自己工作和主流的框架: 在研究好用和新框架. 主流框架教程分享在Java帮帮-免费资源网 其他教程需要时间制作,会陆续分享!!! 152款框架,你还 ...
- 爬虫-lxml用法
安装 pip install lxml 用法 # coding=utf-8 from lxml import etree text = ''' <div> <ul> <l ...
- btcWallet系列之一-grpc模块
btcwallet对外服务 btcwallet除了像btcd对外提供rpc服务以外,还提供了grpc服务,同时grpc采用的是protobuf来实现. 这方便与不同语言进行交互,降低客户端代码编写量. ...
- Debian9下安装Python3 pip
Debian9下安装Python3 pip 使用apt-get安装Python3-pip包 apt-get install python3-pip