XML: 可扩展标记语言(extensible Markup Language)
1、特性与作用
特性:
- xml具有与平台无关性,是一门独立的标记语言。
- xml具有自我描述性。
作用:
- 网络数据传输
- 数据存储
- 配置文件
2、XML文件及语法
- .xml文件是保存XML数据的一种方式
- xml数据也可以以其它方式构建(在内存中构建xml数据)
- 不要将xml语言狭义的理解为XML文件
XML语法格式
2.1 xml文档声明
<?xml version="1.0" encoding="UTF-8"?>
一定在第一行
2.2 标记(元素 / 标签 / 节点)
XML文档,由一个个标记组成。
语法:
开始标记(开放标记):<标记名称>
结束标记(闭合标记):</标记名称>
标记名称:
- 自定义标记遵守命名规范
- 名称可以含字母、数字及其他字符;
- 名称不能以数字或者标点符号开始;
- 名称不能以字符“xml”(XML、Xml)开始;
- 名称不能包含空格、冒号(:); 名称区分大小写;
标记内容:开始标记和结束标记之间是标记内容;
<name> JSONLiu </name>
2.3 一个XML文档中,必须有且仅能有一个根标记。
2.4 标记可以嵌套,但不允许交叉。
2.5 标记的层级结构(字标记、父标记、兄弟标记、后代标记、祖先标记)。
<persons>
<person>
<name>张三</name>
<length>175cm</length>
</person>
<person>
<name>张三</name>
<length>180cm</length>
</person>
</persons>
2.6 标记名称允许重复。
2.7 标记除了开始和结束,还有属性。
标记属性:
- 标记中的属性,在标记开始 中描述,由属性名和属性值组成。
格式:
- 在开始标记中描述属性。
- 可以包含0-n个属性,每个属性是一个键值对。
- 属性名不允许重复,键和值之间使用等号连接,
- 多个属性之间用空格分开。
- 属性值 必须被引号 引住。
2.8 注释
不能写在文档声明之前
注释不能嵌套注释
格式:<!-- 开始 -->结束。
2.9 案例
<?xml version="1.0" encoding="UTF-8" ?>
<books>
<book id="001">
<name><![CDATA[<<三国演义>>]]></name>
<info>东汉末年分三国</info>
</book>
<book id="002">
<name><![CDATA[<<史记>>]]></name>
<info>史家之绝唱</info>
</book>
</books>
2.10 CDATA
CDATA是不应该由XML解析器解析的文本数据,CDATA中所有数据会被XML解析器忽略。
符号:"<" "&"在XML中都是非法的。
语法:
"<![CDATA[" 开始,"]]>"结束。
3、java中解析XML
面试题:
Java中解析XML有几种方式?分别是什么?各有什么优缺点?
四种解析方式。
3.1、SAX解析
解析方式:事件驱动(逐行解析的时候,到某些特殊位置有一些事件触发)。
逐行读取XML文件,每当解析到一个标记的开始、结束、属性、内容时,触发事件;
我们可以编写程序在这些事件发生时,做相应处理
优点:
- 分析能够立即开始,而不是等待所有数据被处理。
-
逐行加载,节省内存,有助于解析大于系统内存的文档。
- 有时不必解析整个文档,可以在满足某个条件时,停止解析。
缺点:
- 单向解析,无法定位文档层次,无法同时访问同一文档的不同部分。(因为逐行解析,当解析第n行时,n-1行已经被释放了)
- 无法得知事件发生时元素层次,只能自己维护节点的父/子关系。
- 只读解析方式,无法修改XML内容。
3.2 DOM解析
与平台和语言无关的方式表示XML的官方W3C标准,分析该结构通常需要加载整个文档和内存中建立文档树模型。程序员可以通过操作文档树,来获取 修改 删除 数据。
优点:
- 文档在内存中加载,允许对数据和结构做出更改;
- 访问是双向的,可以在任何时候在树中双向解析数据;
缺点: - 文档全部加载在内存中,资源消耗大。
3.3 JDOM解析
目的是成为java特定文档模型,简化了与XML交互并且比DOM实现更快。
JDOM文档声明其目的是"使用20%(或更少)的精力解决80%(或更多)JAVA/XML问题"。
优点:
- 使用类而不是接口,简化了DOM的API。
- 大量使用了JAVA集合类,方便了JAVA开发人员。
缺点: - 没有较好的灵活性。
- 性能不是那么的优异。
3.4 DOM4J解析
它是JDOM的一种智能分支。他合并了许多超出基本XML文档表示的功能,包括集成XPath、XML Schema支持以及用于大文档或流化文档的 基于事件的处理。它还提供了构建文档表示选项,DOM4J是一个非常优秀的 java xml api ,具有性能优异、功能强大、极端已用特点,同时也是一个开放源码的软件。目前许多开源项目大量采用DOM4J,例如:Hibernate。
4、DOM4J解析XML
步骤:
- 引入jar包:dom4j.jar;
- 创建一个指向xml文件的输入流 FileInputStream fis=new FileInputStream(“xml文件路径”);
- 创建一个xml读取工具对象 SAXReader sr=new SAXReader();
- 使用读取工具对象读取 XML输入流,得到文档对象 Document doc=sr.read(fis);
- 通过文档对象,获取XML文档中的根元素 Element root=doc.getRootElement();
4.1 解析本地XML
public static Element xmlDocRoot(String filePath) throws IOException, DocumentException {
FileInputStream fis=new FileInputStream(filePath);
SAXReader sr=new SAXReader();
Document read = sr.read(fis);
Element root=read.getRootElement();
fis.close();
return root;
}
Element root= XmlUtil.xmlDocRoot("book.xml");
Element book = root.addElement("book");
book.addAttribute("id","003");
book.addElement("name");
book.element("name").addCDATA("<<山海经>>");
book.addElement("info");
book.element("info").addCDATA("神话传说故事");
List<Element> elements=root.elements();
for (Element e:elements){
System.out.println(e.attributeValue("id"));
System.out.println(e.elementText("name"));
System.out.println(e.elementText("info"));
}
4.2 解析网络XML
public static Element urlXMLRoot(String urlPath) throws IOException, DocumentException {
URL url=new URL(urlPath);
URLConnection urlConnection = url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
Document doc=new SAXReader().read(inputStream);
Element root=doc.getRootElement();
inputStream.close();
return root;
}
String phone="18859275886";
Element root1=XmlUtil.urlXMLRoot("http://apis.juhe.cn/mobile/get?phone="+phone+"&dtype=xml&key=9f3923e8f87f1ea50ed4ec8c39cc9253");
String resultCode=root1.elementText("resultcode");
if("200".equals(resultCode)){//解析成功
Element result=root1.element("result");
//省 市 运营商
String province=result.elementText("province");
String city=result.elementText("city");
String company=result.elementText("company");
System.out.println(phone+"来自:"+(province.equals(city)?city:province+","+city)+"。运营商:"+company);
}
5、文档对象 Document
指的是加载到内存中的整个XML文档。
常用方法:
返回值类型 | 方法名称 | 描述 |
---|---|---|
Element | getRootElement() | 通过文档对象获取XML文档中根节点元素对象 |
Element | addElement() | 添加根节点 |
6、元素对象 Element
指的是XML文档中的单个节点。
返回值类型 | 方法名称 | 描述 |
---|---|---|
String | getName() | 获取节点名称 |
String | getText() | 获取节点内容 |
String | setText() | 设置节点内容 |
Element | element(String name) | 根据子节点名称,获取匹配名称的第一个子节点。 |
List | elements() | 获取所有的子节点 |
String | attributeValue(String attributeName) | 根据节点的属性名称,获取节点属性值 |
String | elementText(String childName) | 获取子节点文本内容 |
Element | addElement(String childName) | 添加子节点 |
void | addAttribute(String name,String value) | 添加属性和值 |
7、DOM4J XPath解析XML
通过路径快速查找一个或者一组元素。
路径表达式:
/ : 从根节点开始查找
// : 从发起位置开始查找后代节点
. : 查找当前节点
… :查找父节点
@ :选择属性
属性使用方式:
[@属性名=‘值’]
[@属性名>‘值’]
[@属性名<‘值’]
[@属性名!=‘值’]
例如://book[@id=‘1’]//name
使用步骤:
通过Node类的两个方法来完成查找,Node是Document与Element的父接口。
返回值类型 | 方法名称 | 描述 |
---|---|---|
Element | selectSingleNode(String pathExpression) | 通过路径表达式查找匹配的单个节点。 |
List | selectNodes(String pathExpression) | 通过路径表达式查找匹配的节点。 |
8、Java生成XML
使用步骤:
- 通过文档帮助器(DocumentHelper)创建空文档对象:Document doc=DocumentHelper.createDocument();
- 通过文档对象,向其中添加根节点:Element e=doc.addElement(“根节点名称”);
- 通过根节点root对象,丰富子节点:Element e=root.addElement(“子节点名称”);
- 创建一个文件输出流,用于存储XML文件:FileOutputStream fos=new FileOutputStream(“xml文件路径”);
- 将文件输出流装换为文档输出流:XMLWriter xw=new XMLWriter(fos);
- 写出文档:xw.write(doc);
- 释放资源:xw.close();
9、XStream的使用
快速的将java对象装换为xml字符串。
使用步骤:
- 创建XStream对象:XStream xs=new XStream();
- 修改类生成的节点名称(默认名称:包名.类名) xs.alias(“节点名称”,类名.class);
- 传入对象,生成XML字符串:String xml=xs.toXML(对象);