XML
XML是可扩展标记语言,是一种简单的数据存储语言,使用一系列简单的标记来描述结构化数据。
XML的特点:
- XML与操作系统,编程语言的开发平台都无关
- 规范统一,实现不同系统之间的数据交互
XML 的文档结构
1、XML 声明
<?xml version="1.0"encoding="UTF-8"?> 表示XML声明,用以标明该文件是一个XML文档。XML文档总是以XML声明开始,它定义了XML的版本和所使用的编码等信息。
XML声明由以下几个部分组成。
- version:文档符合 XML 1.0 规范
- encoding:文档字符编码,默认为 ”UTF-8“
对于任何一个XML文档,其声明部分都是固定格式
2、标签
在 XML 中,通过用jiankuoh<>括起来的各种标签来标记数据,标签成对使用来界定字符数据。
缺少结束标签及如下的嵌套方式是错误的。
<title>
<name>
XML 编程
</title>
</name>
3、元素
XML 文档的主要部分是元素,如”王珊“ 就是一个元素。元素由开始标签、结束标签和元素内容标签组成。
元素的命名规则如下
- 名称中可以包含字母、数字或其他的字符
- 名称不能以数字或标点符号开始
- 名称不能以字符”xml“ 开始
- 名称中不能包含空格
4、根元素
每个 XML 文档必须由且仅有一个根元素。
根元素的特点如下:
- 根元素是一个完成包括文档中其他所有元素的元素
- 根元素的起始标签要放在所有其他元素的起始标签之前
- 根元素的结束表要放在所有其他元素的结束标签之后
5、属性
这个标签使用 id 属性描述图书的编号信息,属性定义的语法如下:
<元素名 属性名=“属性值”>
属性值用双引号包裹。
注意
-
一个元素可以有多个属性,多个属性之间用空格隔开,基本格式如下
<元素名 属性名="属性值" 属性名="属性值"/>
6、XML 中的特殊字符的处理
有时在元素的文本中涉及一些特殊字符(如 <、 >、’、 "、 &),而 XML 文档结构本身就用到了这几个特殊字符,会引起文档结构解析错误
以下有两种办法可以解决
-
对这5个特殊字符进行转义,也就是使用 XML 中的预定义实体这些字符
-
< < > > & & " " ' '
-
在元素的文本中使用 CDATA 节处理。CDATA 节中的所有字符都会被当做元素字符数据的常量部分,而不是 XML 标签。定义 CDATA 节的语法如下
-
<![CDATA[ 要显示的字符 ]]>
7、XML 中的注释
<!--注释内容-->
8、格式良好的 XML 文档
格式良好的 XML 文档需要遵循如下规则
- 有XML 声明语句
- 有且仅有一个根元素
- 标签大小写敏感
- 属性值用双引号包裹
- 标签成对/空标签关闭
- 元素正确嵌套
XML 的应用场景注意体现在以下几点
- 数据存储
- 数据交换
- 数据配置
解析 XML 概述
目前常用的 XML 解析技术有4种
1、DOM
基于 XML 的树结构来完成解析的,DOM 解析 XML 文档时,会根据读取的文档,构建一个驻留内存的树结构,然后就可以使用 DOM API 来操作这个树结构。DOM 解析 XML 的方式非常适用于多次访问 XML 的程序,但是 DOM 解析却时比较消耗资源的。
2、SAX
基于事件的解析,它是为了解决 DOM 解析的资源消耗而出现的。他不像 DOM 那样需要建立一棵完整的文档树,而是通过事件处理器完成对文档的解析。因为 SAX 解析不用事先调入整个文档,所以他的优势就是占用资源少,内存消耗小。
注意
DOM 是 W3C 组织提供的解析 XML 文档的标准接口,SAX 是社区产物,但也是一种事实上的标准。
3、JDOM
JDOM是针对 Java 的特点文档模型,它简化了与 XML 的交互且比使用 DOM 更快。区别,JDOM 仅使用具体类而不是使用接口,但是也限制了灵活性。JDOM 的优势在于”使用20% 的精力解决 80% 的 Java/XML问题“
4、DOM4J
一个非常优秀的 Java XML API,具有性能优异、功能强大和易用的特点,同时它也是一个开源库。
DOM4J用于在 Java 平台上使用 Java 集合框架处理 XML、XPath和 XSLT,并与DOM、SAX和JAXP完全集成。
DOM4J大量使用接口,面向接口编程使它比 JDOM 更加灵活。
使用 DOM 读取 XML 数据
DOM 概念
DOM 是 文档对象模型,DOM 把 XML 文件映射成一颗倒挂的”树“,以根元素为根节点。每个节点都以对象形式存在。通过存取这些对象就能够存取 XML 文档的内容
DOM 解析使用到的类都在这些包中
org.w3c.dom:W3C 推荐使用到的类都在这些包中
org.xml.sax:用于使用 SAX 解析 XML 文档的接口
javax.xml.parsers:解析器工厂工具,获取并配置特殊的分析器
使用 DOM 解析 XML 文档的步骤如下:
- 创建解析器工厂对象,即 DocumentBuilderFactory 对象
- 有解析器工厂对象创建解析器对象,即 DocumentBuilder 对象
- 有解析器对象对指定的 XML 文档进行解析,构建相应的 DOM 树,创建 Dcument 对象
- 以 Document 对象为起点对 DOM 树的节点进行增加、删除、修改、查询等操作
使用 DOM 解析 XML 时注意使用以下对象
1、Node对象:
DOM 结构中最基本的对象,代表了文档树种的一个抽象节点
注意方法如下:
getChildNodes(): 返回包含此节点所以子节点的NodeList
getFirstChild(): 如果节点存在字节的,则返回第一个字节的
getLastChild(): 如果节点存在子节点,则返回最后一个兄弟节点
getNextSibling(): 返回在 DOM 树中这个节点的下一个兄弟节点
getPreviousSibling():返回在 DOM 树中这个节点的上一个兄弟节点
getNodeName(): 返回节点的名称
getNodeValue(): 返回节点的值
getNodeType(): 返回节点的类型
2、NodeList 对象
包含了一个或多个节点的列表。
getLength() 返回列表的长度
item(int index) 返回指定位置的 Node 对象
3、Document 对象
代表整个 XML 文档,所有其他的 Node 都以一定的顺序包含在 Document 对象之内,排列成一个树状结构,可以通过遍历这颗”树“来得到 XML 文档的所有内容。
getElementsByTagName(String name): 返回一个 NodeList 对象,包含了所有给定标签名称的标签
getDocumentElement(): 返回一个代表这个 DOM 树的根节点的 Element 对象
4、Element 对象
XML 文档中的标签元素,继承自 Node,是 Node 最主要的子对象。
getAttribute(String attributename): 返回标签中给定属性名称的属性的值
getElementsByTagName(String name): 返回具有给定标签名称的所有后代 Elements 的NodeList。
注意
XML 文档中空白符也会被作为对象映射在 DOM 树种。直接调用 Node 对象的 getChildNodes() 方法有时候会有些问题,有时不能够返回所期望的 NodeList 元素对象列表。
解决的办法如下:
1、使用 Element 的 getElementsByTagName(String name),返回的 NodeList 就是所期待的对象。然后,可以用 item() 方法提取想要的元素
2、调用 Node 的 getChildNodes() 方法得到 NodeList 对象,每次通过 item() 方法提取 Node 对象后判断 node.getNodeType()==Node.ELEMENT_NODE,即判断是否是元素节点,如果为true,则表示是想要的元素
使用 DOM4J 解析 XML
1、DOM4J API 概述
Attribute:定义了XML的属性
Branch:为能够包含字节的节点
CDATA:定义了 XML CDATA 区域
CharacterData:是一个标识接口,标识基于字符的节点,如 CDATA、Comment 和 Text
Comment:定义了 XML 注释的行为
Document;定义了 XML 文档
DocumentType:定义 XML DOCTYPE 声明
Element:定义 XML 元素
ElementHandler:定义了 Element 对象的处理器
ElementPath:被 ElementHandler 使用,用于取得当前正在处理的路径层次信息
Entity:定义 XML 实体
Node:为 dom4j 中的所有 XML 节点定义了多态行为
NodeFilter:定义了在 dom4j 节点中产生的一个滤镜或谓词的行为
ProcessingInstruction:定义了 XML 处理指令
Text:定义 XML 文本节点
Visitor:用于实现 Visitor 模式
XPath:通过分析一个字符串提供一个 XPath 表达式
2、使用 DOM4J 操作 XML 数据
-
Document 对象相关
-
读取 XML 文件,获取 DOcument 对象 SAXReader reader = new SAXReader(); Document document = reader.read(new File("input.xml"));
-
节点相关
-
获取文档的根元素
-
Element rootElm = document.getRootElement();
-
-
取得某节点的单个子节点
-
Element memberElm = rootElm.element("member"); //”member“是节点名
-
-
取得节点的文字
-
String text = memberElm.getText();
-
-
也可以用:
-
String text = rootElm.elementText("name"); //取得根元素下的name子节点的文字
-
-
取得某节点下名为 ”member“ 的所有子节点并进行遍历
-
List nodes = rootElm.elements("member"); for(Iterator it = nodes.iterator(); it.hasNext();){ //…… }
-
-
对某节点下的所有子节点进行遍历
-
for(Iterator it = rootElm.elementIterator();it.hasNext();){ Element element = (Element)it.next(); }
-
-
在某节点下添加子节点。newMemberElm是某个已存在的节点
-
Element ageElm = newMemberElm.addElement("age");
-
-
设置节点文字
-
age.setText("29");
-
-
删除某节点
-
parentElm.remove(childElm); // childElm 是待删除的节点,parentElm 是其父节点
-
-
-
属性相关
-
取得某节点下的某属性
-
Element root = document.getRootElement(); Attribute attribute = root.attribute("size"); //属性名 size
-
-
取得属性的值
-
String text = attribute.getText();
-
-
也可以用:
-
String text2 = root.element("name").attributeValue("firstname");
-
-
遍历某节点的所有属性
-
Element root = document.getRootElement(); for(Iterator it = root.attributeIterator(); it.hasNext();){ Attribute attribute = (Attribute)it.next(); String text = attribute.getText(); System.out.printIn(text); }
-
-
为某节点添加属性
-
newMemberElm.addAttribute("name", "learningdom4j");
-
-
设置属性的值
-
Attribute attribute = root.attribute("name"); attribute.setText("learningdom4j");
-
-
删除某属性
-
Attribute attribute = root.attribute("size"); //属性名 size root.remove(attribute);
-
-
-
将文档写入 XML 文件
-
文档中全为英文,不设置编码格式,直接写入
-
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"))); writer.write(document); writer.close();
-
-
文档中含有中文,设置编码格式再写入
-
OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("GBK"); //指定 XML 编码 XMLWriter writer = new XMLWriter(new FileWriter("output.xml"), format); writer.write(document); writer.close();
-
-