Java 高级篇
XML
可扩展标记语言(eXtensible Markup Language)。
特性:
-
xml具有平台无关性, 是一门独立的标记语言.
-
xml具有自我描述性
应用场景
-
网络数据传输.
-
数据存储
-
配置文件
文件格式
-
.XML文件是保存XML数据的一种方式
-
XML数据也可以以其他的方式存在(如在内存中构建XML数据)。
-
不要将XML语言狭隘的理解成XML文件
解析方式
SAX解析
- SAX(Simple API for XML)解析是按照 xml 文件的顺序一步一步的来解析。
DOM解析
- 分析器将一个 XML 文档转换成一个对象模型的集合(通常称为 DOM 树),应用程序正是通过对这个对象模型的操作,来实现对 XML 文档数据的操作。
JDOM解析
- JDOM 是一种使用 XML 的独特 Java 工具包,用于快速开发 XML 应用程序。JDOM 是一个开源项目,它基于树形结构,利用纯 Java 的技术对 XML 文档实现解析、生成、序列化及多种操作。
DOM4J解析
- dom4j 是一个简单的开源库,用于处理 XML、 XPath 和 XSLT,它基于 Java 平台,使用 Java 的集合框架,全面集成了 DOM,SAX 和 JAXP。
区别
-
DOM
优点:
1、允许应用程序对数据和结构做出更改。
2、访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。缺点:
1、通常需要加载整个XML文档来构造层次结构,消耗资源大 -
SAX
优点:
1、不需要等待所有数据都被处理,分析就能立即开始。
2、只在读取数据时检查数据,不需要保存在内存中。
3、可以在某个条件得到满足时停止解析,不必解析整个文档。
4、效率和性能较高,能解析大于系统内存的文档。缺点:
1、需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),使用麻烦。
2、单向导航,很难同时访问同一文档的不同部分数据,不支持XPath。
那我们开发中使用哪种解析比较多呢?
答案是:DOM解析
-
DOM解析将一个XML文件当做一个对象,我们可以以操作一个对象的方法简单的操作XML,而且DOM解析有很多分支,DOM4J,JDOM有面向接口,支持XPATH,功能非常强大
-
DOM解析的缺点是消耗内存,而实际上开发中XML文件一般都是一些配置文件,大小都是几K,所以缺点忽略不计。
DOM4J常用方法
这是中国手机号归属地查询网址返回的结果,结果为XML,我们试着解析这个文件。
<?xml version="1.0" encoding="UTF-8" ?>
<root id="1">
<success status="200" key="12sr">1</success>
<result>
<status>ALREADY_ATT</status>
<phone>13800138000</phone>
<area>010</area>
<postno>100000</postno>
<att>中国,北京</att>
<ctype>中国移动138卡</ctype>
<par>1380013</par>
<prefix>138</prefix>
<operators>中国移动</operators>
<style_simcall>中国,北京</style_simcall>
<style_citynm>中华人民共和国,北京市</style_citynm>
</result>
</root>
DOM术语
获取节点名
public static void main(String[] args) throws FileNotFoundException, DocumentException {
//创建DOM4J解析工具
SAXReader reader = new SAXReader();
Document doc = reader.read(new FileInputStream(new File("E:\\Phone.xml")));
//获取根节点
Element rootElement = doc.getRootElement();
System.out.println("根节点:"+rootElement.getName());
//获取根节点的所有子节点的数组
List<Element> elements = rootElement.elements();
//遍历数组
for (Element element : elements) {
System.out.println("子节点:"+element.getName());
}
//通过标签名获得子节点
Element result = rootElement.element("result");
System.out.println("result: "+result.getName());
}
结果
根节点:root
子节点:success
子节点:result
result: result
获取属性值
public static void main(String[] args) throws FileNotFoundException, DocumentException {
//创建DOM4J解析工具
SAXReader reader = new SAXReader();
Document doc = reader.read(new FileInputStream(new File("Phone.xml")));
//获取根节点
Element rootElement = doc.getRootElement();
//获取根节点的ID属性值
String id = rootElement.attributeValue("id");
System.out.println("id="+id);
Element success = rootElement.element("success");
List<Attribute> attributes = success.attributes();
for (Attribute attribute : attributes) {
System.out.println(attribute.getName()+": "+attribute.getValue());
}
}
结果
id=1
status: 200
key: 12sr
获取文本内容
public static void main(String[] args) throws FileNotFoundException, DocumentException {
//创建DOM4J解析工具
SAXReader reader = new SAXReader();
Document doc = reader.read(new FileInputStream(new File("Phone.xml")));
//获取根节点
Element rootElement = doc.getRootElement();
//获取result节点的内容
Element result = rootElement.element("result");
//获取result节点的子节点数组
List<Element> elements = result.elements();
//遍历打印result所有子节点的文本内容
for (Element element : elements) {
System.out.println(element.getName()+": "+element.getText());
}
}
结果
status: ALREADY_ATT
phone: 13800138000
area: 010
postno: 100000
att: 中国,北京
ctype: 中国移动138卡
par: 1380013
prefix: 138
operators: 中国移动
style_simcall: 中国,北京
style_citynm: 中华人民共和国,北京市
创建一个XML
直接上代码
public static void main(String[] args) {
File file = new File("E:\\ideaProjects\\study\\KaiKeBa\\src\\com\\kaikeba\\course03pro\\createXmlFile.xml");
createDom4j(file);
}
public static void createDom4j(File file) {
try {
// 创建一个Document实例
Document doc = DocumentHelper.createDocument();
// 添加根节点
Element root = doc.addElement("root");
// 在根节点下添加第一个子节点
Element oneChildElement= root.addElement("person").addAttribute("attr", "root noe");
oneChildElement.addElement("people")
.addAttribute("attr", "child one")
.addText("person one child one");
oneChildElement.addElement("people")
.addAttribute("attr", "child two")
.addText("person one child two");
// 在根节点下添加第一个子节点
Element twoChildElement= root.addElement("person").addAttribute("attr", "root two");
twoChildElement.addElement("people")
.addAttribute("attr", "child one")
.addText("person two child one");
twoChildElement.addElement("people")
.addAttribute("attr", "child two")
.addText("person two child two");
// xml格式化样式
// OutputFormat format = OutputFormat.createPrettyPrint(); // 默认样式
// 自定义xml样式
OutputFormat format = new OutputFormat();
format.setIndentSize(2); // 行缩进
format.setNewlines(true); // 一个结点为一行
format.setTrimText(true); // 去重空格
format.setPadText(true);
format.setNewLineAfterDeclaration(false); // 放置xml文件中第二行为空白行
// 输出xml文件
XMLWriter writer = new XMLWriter(new FileOutputStream(file), format);
writer.write(doc);
System.out.println("dom4j CreateDom4j success!");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
运行结果
<?xml version="1.0" encoding="UTF-8"?>
<root>
<person attr="root noe">
<people attr="child one">person one child one</people>
<people attr="child two">person one child two</people>
</person>
<person attr="root two">
<people attr="child one">person two child one</people>
<people attr="child two">person two child two</people>
</person>
</root>
使用代码创建XML文件还是比较麻烦的,在XML体比较少的情况下,还是推荐人肉输入。如果XML用于存储大量内容,要用很多循环嵌套输出,那么就用DOM4J进行解析。