Android:XML简介 & 解析方式对比(DOM、SAX、PULL)
目录

1. 定义
XML,即 extensible Markup Language ,是一种数据标记语言 & 传输格式
2. 作用
对数据进行标记(结构化数据)、存储 & 传输
区别于
html:html用于显示信息;而XML用于存储&传输信息
3. 特点

4. 语法
- 元素要关闭标签
< p >this is a bitch <p> - 对大小写敏感
< P >这是错误的<p>
< p >这是正确的 <p>
- 必须要有根元素(父元素)
<root>
<kid>
</kid>
</root>
- 属性值必须加引号
<note date="16/08/08">
</note>
- 实体引用
| 实体引用 | 符号 | 含义 |
|---|---|---|
| <; | < | 小于 |
| > ; | > | 大于 |
| &; | & | 和浩 |
| &apos; | ‘ | 单引号 |
| "; | " | 双引号 |
元素不能使用&(实体的开始)和<(新元素的开始)
- 注释
``
- XML的元素、属性和属性值
文档实例
<bookstore>
<book category="CHILDREN">
<title lang="en"> Harry Potter </title>
<author> JK.Rowling</author>
</book>
<book category="WEB">
<title lang="en"> woshiPM </title>
<author>Carson_Ho</author>
</book>
</bookstore>
其中,<bookstore>是根元素;<book>是子元素,也是元素类型之一;而<book>中含有属性,即category,属性值是CHILDREN;而元素<author>则拥有文本内容( JK.Rowling)
- 元素与属性的差别
属性即提供元素额外的信息,但不属于数据组成部分的信息。
范例一
<bookstore>
<book category="CHILDREN">
<title lang="en"> Harry Potter </title>
<author> JK.Rowling</author>
</book>
范例二
<bookstore>
<book >
<category>CHILDREN<category>
<title lang="en"> Harry Potter </title>
<author> JK.Rowling</author>
</book>
范例一和二提供的信息是完全相同的。
一般情况下,请使用元素,因为
- 属性无法描述树结构(元素可以)
- 属性不容易拓展(元素可以)
使用属性的情况:用于分配ID索引,用于标识XML元素。
实例
<bookstore>
<book id = "501">
<category>CHILDREN<category>
<title lang="en"> Harry Potter </title>
<author> JK.Rowling</author>
</book>
<book id = "502">
<category>CHILDREN<category>
<title lang="en"> Harry Potter </title>
<author> JK.Rowling</author>
</book>
<bookstore>
上述属性(id)仅用于标识不同的便签,并不是数据的组成部分
- XML元素命名规则
- 不能以数字或标点符号开头
- 不能包含空格
- 不能以xml开头
CDATA
不被解析器解析的文本数据,所有xml文档都会被解析器解析(cdata区段除外)
<![CDATA["传输的文本 "]]>PCDATA
被解析的字符数据
5. XML树结构
XML文档中的元素会形成一种树结构,从根部开始,然后拓展到每个树叶(节点),下面将以实例说明XML的树结构。
- 假设一个XML文件如下
<?xml version ="1.0" encoding="UTF-8"?>
<简历>
<基本资料>
<求职意向>
<自我评价>
<其他信息>
<联系方式>
<我的作品>
</简历>
其树结构如下
树结构 .pngXML节点解释
XML文件是由节点构成的。它的第一个节点为“根节点”。一个XML文件必须有且只能有一个根节点,其他节点都必须是它的子节点。
this 代表整个XML文件,它的根节点就是 this.firstChild 。 this.firstChild.childNodes 则返回由根节点的所有子节点组成的节点数组。

每个子节点又可以有自己的子节点。节点编号由0开始,根节点的第一个子节点为 this.firstChild.childNodes[0],它的子节点数组就是this.firstChild.childNodes[0].childNodes 。

根节点第一个子节点的第二个子节点 this.firstChild.childNodes[0].childNodes[1],它返回的是一个XML对象(Object) 。这里需要特别注意,节点标签之间的数据本身也视为一个节点 this.firstChild.childNodes[0].childNodes[1].firstChild ,而不是一个值。

我们解析XML的最终目的当然就是获得数据的值:this.firstChild.childNodes[0].childNodes[1].firstChild.nodeValue 。
请注意区分:节点名称(<性别></性别>)和之间的文本内容(男)可以当作是节点,也可以当作是一个值
节点:
名称:this.firstChild.childNodes[0].childNodes[1]
文本内容:this.firstChild.childNodes[0].childNodes[1].firstChild
值:
名称:this.firstChild.childNodes[0].childNodes[1].nodeValue
(节点名称有时也是我们需要的数据)
文本内容:this.firstChild.childNodes[0].childNodes[1].nodeName
在了解完XML之后,是时候来学下如何进行XML的解析了
6. 解析方式
- 解析
XML,即从XML中提取有用的信息 XML的解析方式主要分为2大类:
示意图
6.1 DOM方式
- 简介
Document Object Model,即 文件对象模型,是 一种 基于树形结构节点 & 文档驱动 的XML解析方法
定义了访问 & 操作xml文档元素的方法和接口
- 解析原理

- 具体解析实例
// 假设需要解析的XML文档如下(subject.xml)
<?xml version ="1.0" encoding="UTF-8"?>`
<code>
<language id="1">
<name>Java</name>
<usage>Android</usage>
</language>
<language id="2">
<name>Swift#</name>
<usage>iOS</usage>
</language>
<language id="3">
<name>Html5</name>
<usage>Web</usage>
</language>
</code>
// 解析的核心代码
public static List<subject> getSubjectList(InputStream stream)
{ tv = (TextView)findViewById(R.id.tv);
try {
//打开xml文件到输入流
InputStream stream = getAssets().open("subject.xml");
//得到 DocumentBuilderFactory 对象
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//得到DocumentBuilder对象
DocumentBuilder builder = builderFactory.newDocumentBuilder();
//建立Document存放整个xml的Document对象数据
Document document = builder.parse(stream);
//得到 XML数据的"根节点"
Element element = document.getDocumentElement();
//获取根节点的所有language的节点
NodeList list = element.getElementsByTagName("language");
//遍历所有节点
for (int i= 0;i<=list.getLength();i++){
//获取lan的所有子元素
Element language = (Element) list.item(i);
//获取language的属性(这里即为id)并显示
tv.append(lan.getAttribute("id")+"\n");
//获取language的子元素 name 并显示 tv.append(sub.getElementsByTagName("name").item(0).getTextContent()+"\n");
//获取language的子元素usage 并显示 tv.append(sub.getElementsByTagName("usage").item(0).getTextContent()+"\n");
}
- 特点 & 应用场景

6.2 SAX 方式
简介
即Simple API for XML,一种 基于事件流驱动、通过接口方法解析 的XML解析方法解析原理
示意图
- 解析实例
在使用SAX解析XML文档时,关键在于 自定义自己的Handler处理类 & 复写对应方法
public class MyHandler extends DefaultHandler{
@Override
public void startDocument() throws SAXException{
}
@Override
public void startElement(String uri,String localName,String qName,
Attributes attributes) throws SAXException{
}
@Override
public void characters(char[] ch,int start,int length) throws SAXException{
}
@Override
public void endElement(String uri,String localName,String qName)
throws SAXException{
}
@Override
public void endDocument() throws SAXException{
}
}
- 特点 & 应用场景

6.3 PULL解析
- 简介
一种 基于事件流驱动 的XML解析方法
- 解析原理

- 解析模板代码
注:
Android中自带了Pull解析的jar包,故不需额外导入第三方jar包
// Pull使用循环解析
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xml.setInput(new StringReader(xmlData));
int eventType = xmlPullParser.getEventType();
while(eventType!=XmlPullParser.END_DOCUMENT){
String nodeName = xmlPullParser.getName();
switch(eventType){
case XmlPullParser.START_DOCUMENT:{}
case XmlPullParser.START_TAG:{}
case XmlPullParser.END_TAG:{}
}
eventType = parser.next();
}
- 解析实例
public class MainActivity extends Activity {
private EditText et;
private Button myButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButton = (Button) this.findViewById(R.id.btn01);
et = (EditText) this.findViewById(R.id.edittext01);
myButton.setOnClickListener(new OnClickListener() {
//可变字符序列,比StringBuffer块
StringBuilder sb = new StringBuilder("");
Resources res = getResources();
XmlResourceParser xrp = res.getXml(R.xml.subject);
@Override
public void onClick(View v) {
int counter = 0;
try {
// 判断是否到了文件的结尾
while (xrp.getEventType() != XmlPullParser.END_DOCUMENT) {
//文件的内容的起始标签开始,这里的起始标签是subject.xml文件里面<subjects>标签下面的第一个标签
int eventType=xrp.getEventType();
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.START_TAG:
String tagname = xrp.getName();
if (tagname.endsWith("language")) {
counter++;
sb.append("这是第" + counter + "种语言"+"\n");
//可以调用XmlPullParser的getAttributte()方法来获取属性的值
sb.append("语言id是:"+xrp.getAttributeValue(0)+"\n");
}
else if(tagname.equals("name")){
//可以调用XmlPullParser的nextText()方法来获取节点的值
sb.append("语言名称是:"+xrp.nextText()+"\n");
}
else if(tagname.equals("teacher")){
sb.append("用途是:"+xrp.nextText()+"\n");
}
break;
case XmlPullParser.END_TAG:
break;
case XmlPullParser.TEXT:
break;
}
//解析下一个事件
xrp.next();
}
//StringBuilder要调用toString()方法并显示
et.setText(sb.toString());
} catch (XmlPullParserException e) {
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
- 特点 & 应用场景

6.4 解析方式对比

7. 总结
- 本文全面介绍了现今主流的数据传输格式
XML,下面用一张图总结XML的主流解析方法
示意图
作者:Carson_Ho
链接:https://www.jianshu.com/p/e636f4f8487b
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
Android:XML简介 & 解析方式对比(DOM、SAX、PULL)的更多相关文章
- Android 通过Dom, Sax, Pull解析网络xml数据
这篇文章不是完全原创,XML解析的部分参考了 liuhe688 的文章.文章地址:http://blog.csdn.net/liuhe688/article/details/6415593 这是一个几 ...
- XML的解析方式(DOM、SAX、StAX)
(新) XML的解析方式(DOM.SAX.StAX) 博客分类: XML 一般来说,解析XML文件存在着两种方式,一种是event-based API,比如说象SAX,XNI. 第二种是tree ...
- - XML 解析 总结 DOM SAX PULL MD
目录 目录 XML 解析 总结 DOM SAX PULL MD 几种解析方式简介 要解析的内容 DOM 解析 代码 输出 SAX 解析 代码 输出 JDOM 解析 代码 输出 DOM4J 解析 代码 ...
- xml的解析方式的简介
xml的解析的简介(写到java代码) *xml是一个标记型文档 *js使用dom解析标记型文档? -根据html的层级结构,在内存中分配一个树形结构,把html的标签,属性和文本都封装成对象 -do ...
- 二、Android XML数据解析
XML,可扩展标记语言.可以用来存储数据,可以看做是一个小型的数据库,SharedPreference就是使用XML文件存储数据的,SQLite底层也是一个XML文件,而在网络应用方面,通常作为信息的 ...
- 黑马day01 xml 的解析方式
XML编程:利用java程序去增删改查(CRUD)xml中的数据 解析思想: dom解析 sax解析 基于这两种解析思想市面上就有了非常多的解析api sun jaxp既有dom方式也有sax方式,而 ...
- :Android网络编程--XML之解析方式:SAX
任何放置在资源(res)目录下的内容可以通过应用程序的R类访问,这是被Android编译过的,而任何放置在资产(assets)目录下的内容会保持它的原始文件格式,为了读取它们,必须使用AssetMan ...
- Java 解析 xml 常见的4中方式:DOM SAX JDOM DOM4J
Java 四种解析 XML 的特点 1.DOM 解析: 形成了树结构,有助于更好的理解.掌握,且代码容易编写. 解析过程中,树结构保存在内存中,方便修改. 2.SAX 解析: 采用事件驱动模式,对内存 ...
- 解析XML:DOM,SAX,PULL
Android解析XML有三种方式:DOM(document object model).SAX(simple api XML).PULL 1.DOM DOM解析XML文件时,会将XML文件的所有内容 ...
随机推荐
- LOJ6045 雅礼集训 2017 Day8 价(最小割)
由Hall定理,任意k种减肥药对应的药材数量>=k.考虑如何限制其恰好为k,可以将其看作是使对应的药材数量尽量少. 考虑最小割.建一个二分图,左边的点表示减肥药,右边的点表示药材.减肥药和其使用 ...
- Js更改样式导致hover效果消失
[问题来源] 今天做单次倒计时,利用JS更改了button样式之后,再次点击时,发现hover效果消失. 原因: CSS的优先级问题导致 [解决方法] 利用!important提高hover的优先级 ...
- SpringBoot基础入门
1.SpringBoot核心相关内容 1.1入口类 SpringBoot通常有一个入口类*Application,内部有一个main方法,是启动SpringBoot的入口.使用@SpringBootA ...
- day30 __new__ 以及单例模式
__new__ # __new__ # object.__new__() class A : def __init__(self): self.x = 1 print("init执行啦&qu ...
- 通俗理解TCP/IP协议三次握手四次分手流程
转自:https://blog.csdn.net/special23/article/details/54137298 三次握手流程 客户端发个请求“开门呐,我要进来”给服务器 服务器发个“进来吧,我 ...
- hihocoder部分题解
hihocoder1609 数组分拆II [dp] 给定数组,问有多少种拆法,使得每一段不出现重复的数字,且要保证分组数最少.(1e5) 题解: O(n) d[i]表示1~i最小划分的段数, f[i] ...
- 学习Spring Boot:(二十三)Spring Boot 中使用 Docker
前言 简单的学习下怎么在 Spring Boot 中使用 Docker 进行构建,发布一个镜像,现在我们通过远程的 docker api 构建镜像,运行容器,发布镜像等操作. 这里只介绍两种方式: 远 ...
- 小整数池和intern机制
在python中,为了优化速度,避免频繁申请和销毁内存空间,python使用小整数池来缓存 range(-5,257) 之间的整数(这里不包含257),这些小整数在赋值引用时使用的都是同一个对象和内存 ...
- FFMEPG -- A ffmpeg and SDL Tutorial : tutorial05
修改了同步播放ffmpeg问题.并且增加可以放大视频. // tutorial05.c // A pedagogical video player that really works! // // C ...
- Linux下定时器
http://unix8.net/linux%E4%B8%8B%E5%AE%9A%E6%97%B6%E5%99%A8.html 一. 基础知识 1.时间类型.Linux下常用的时间类型有4个:time ...





