博文地址

我的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的更多相关文章

  1. Android 通过Dom, Sax, Pull解析网络xml数据

    这篇文章不是完全原创,XML解析的部分参考了 liuhe688 的文章.文章地址:http://blog.csdn.net/liuhe688/article/details/6415593 这是一个几 ...

  2. xml解析中的sax解析

    title: xml解析中的sax解析 tags: grammar_cjkRuby: true --- SAXPasser 类: parser(File file, DefaultHandler ha ...

  3. 解析XML:DOM,SAX,PULL

    Android解析XML有三种方式:DOM(document object model).SAX(simple api XML).PULL 1.DOM DOM解析XML文件时,会将XML文件的所有内容 ...

  4. 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来 ...

  5. XML解析之DOM详解及与SAX解析方法的比较

    XML解析(DOM) XML文件解析方法介绍 我们所用到的NSXMLParser是采用SAX方法解析 SAX(Simple API for XML) 只能读,不能修改,只能顺序访问,适合解析大型XML ...

  6. Java解析XML汇总(DOM/SAX/JDOM/DOM4j/XPath)

    [目录] 一.[基础知识——扫盲] 二.[DOM.SAX.JDOM.DOM4j简单使用介绍] 三.[性能测试] 四.[对比] 五.[小插曲XPath] 六.[补充] 关键字:Java解析xml.解析x ...

  7. IOS中的XML解析之DOM和SAX

    一.介绍 dom是w3c指定的一套规范标准,核心是按树形结构处理数据,dom解析器读入xml文件并在内存中建立一个结构一模一样的“树”,这树各节点和xml各标记对应,通过操纵此“树”来处理xml中的文 ...

  8. java xml解析方式(DOM、SAX、JDOM、DOM4J)

    XML值可扩展标记语言,是用来传输和存储数据的. XMl的特定: XMl文档必须包含根元素.该元素是所有其他元素的父元素.XML文档中的元素形成了一颗文档树,树中的每个元素都可存在子元素. 所有XML ...

  9. XML解析(一) DOM解析

    XML解析技术主要有三种: (1)DOM(Document Object Model)文档对象模型:是 W3C 组织推荐的解析XML 的一种方式,即官方的XML解析技术. (2)SAX(Simple ...

随机推荐

  1. current transaction is aborted, commands ignored until end of transaction block

    current transaction is aborted, commands ignored until end of transaction block Error updating datab ...

  2. USB规格及速度

    1. 速度对比 2. 硬件特性 USB2.0四线:5V,D-,D+,GND. USB3.0一般十线:5V,D-,D+,GND,SSTX+,SSTX-,SSRX+,SSRX-,P1_Drain,P2_D ...

  3. AI-图像基础知识-02

    目录 图像坐标系 图像数字化 图像坐标系     在前面的数据标注文章中讲述如何进行标注,而标注后会保留4个坐标点,那么这些坐标点如何表示在图片中的位置?要表示一个点或图形的位置,就需要涉及到坐标系的 ...

  4. shell之命令代换,将当前路径存放在变量中,然后使用变量

    重要的 命令代换`` 反引号 shell先执行该命令,然后将命令的结果存放在 变量中 例如 var=`pwd` echo $var 也可以用其$()替换 var=$(date) echo $var 删 ...

  5. Candies POJ - 3159

    题目链接:https://vjudge.net/problem/POJ-3159 思路: 能看出是差分约束的题, 我们想假设一个人是 p(1),另一个人是p(2),他们之间糖果差为w, 那么需要满足的 ...

  6. LCD编程_使用调色板

    在前面的博客中,使用的像素格式都是16bpp,24bpp(24bpp实际实际上就是32bpp)?如果想使用8bpp时,就需要使用调色板. 在以前的博客中,曾经说过,在framebuffer中如果每个像 ...

  7. Scrapy笔记05- Item详解

    Scrapy笔记05- Item详解 Item是保存结构数据的地方,Scrapy可以将解析结果以字典形式返回,但是Python中字典缺少结构,在大型爬虫系统中很不方便. Item提供了类字典的API, ...

  8. GIL全局解释锁

    目录 一 介绍 二 GIL介绍 三 GIL与多线程 四 多线程性能测试 一 介绍 ''' 定义: In CPython, the global interpreter lock, or GIL, is ...

  9. 图解 Java 垃圾回收机制,写得非常好!

    阅读本文大概需要 3.7 分钟. 翻译:Rhys_Lee, AzureSora, 溪边九节, 小小菜鸟鸡 blog.csdn.net/zl1zl2zl3/article/details/9090408 ...

  10. 20189220余超 团队博客——阅读软件app

    项目名称 小说阅读器 项目功能 注册登录 用户信息.用户密码.用户图像修改 书籍分类 书架 书籍搜索(作者名或书籍名) 书籍阅读(仅txt格式,暂不支持PDF等其他格式) 阅读字体.背景颜色.翻页效果 ...