XML
XML
XML的作用
- 可以用来保存数据
- 可以用来做配置文件
- 可以作为数据传输载体
XML的结构
文档声明
文档声明放在XML文档第一行,其参数如下
- version: 解析这个XML的时候,使用什么版本的解析器解析
<?XML version="1.0" ?>
- encoding: 解析XML中的文字的时候,使用什么编码来翻译
<?XML version="1.0" encoding="gbk" ?>
- standalone: 表名该XML文档是否依赖其他XML文档
- no: 该文档会依赖关联其他文档
- yes: 这是一个独立的文档
<?XML version="1.0" encoding="gbk" standalone="no" ?>
encoding详解
encoding规定的是解码的时候用什么版本的解析器解析
而默认文件保存的时候,使用的是GBK的编码保存
文件保存时的编码必须要和解析时的编码相一致
保存文件的见到的ANSI对应的其实是我们的本地编码GBK
为了通用,一般使用UTF-8编码保存XML文件,并将声明中的encoding设置为utf-8
元素定义(标签)
- 元素其实就是XML里的标签,<>括起来的都叫元素,必须成对出现.
- 元素可以嵌套
简单元素: 元素里面包含了普通的文字
复杂元素: 元素里面还可以嵌套其他的元素 - 文档声明下来的第一个元素叫做根元素(根标签),所有其他标签必须嵌套在根元素内.
- 空标签: 既是开始也是结束,一般配合属性来用.
<?XML version="1.0" encoding="UTF-8"?>
<stus>
<stu>
<name>张三</name>
<age/>
</stu>
<stu>
<name>李四</name>
<age/>
</stu>
</stus>
属性定义
属性定义在元素里面, 语法<元素名称 属性名称="属性值"></元素名称>
<?XML version="1.0" encoding="UTF-8"?>
<stus>
<stu id="1161160313">
<name>张三</name>
<age/>
</stu>
<stu id="1161160314">
<name>李四</name>
<age/>
</stu>
</stus>
XML注释
XML注释语法与html注释一样. <!-- 注释内容 -->
注释不允许放置在文档的第一行,必须在文档声明的下面.
<?XML version="1.0" encoding="UTF-8"?>
<!--
这里有两个学生,分别存储姓名与年龄
注释放首行无效,必须放在文档声明以下
-->
<stus>
<stu id="1161160313">
<name>张三</name>
<age/>
</stu>
<stu id="1161160314">
<name>李四</name>
<age/>
</stu>
</stus>
CDATA区
非法字符
XML中有5个预定义的实体引用,用来代表非法字符.
实体引用 | 代表字符 |
---|---|
< | < |
> | > |
& | & |
' | ' |
" | " |
严格来讲,在 XML 中仅有字符 “<“和”&” 是非法的,省略号、引号和大于号是合法的,但把它们替换为实体引用是个好的习惯
CDATA区
如果某段字符串里面有过多的非法字符,并且里面包含了类似标签或者关键字的这种文字,不想让XML的解析器去解析,那么可以使用CDATA来包装.
CDATA语法一般比较少见,通常在服务器给客户端返回数据的时候。
<des><![CDATA[<a href="http://www.baidu.com">个人描述</a>]]></des>
XML解析
XML解析方式
xml解析方式有很多种,但是常用的有两种
- DOM(document object model): 把整个XML文档全部读到内存当中,形成一个DOM树. 整个文档称之为Document对象,属性称之为Attribute对象,所有的节点元素称之为Element对象,文本也可以称之为Text对象,以上所有的对象都可以称之为Node节点.
- SAX(simple API for XML): 基于事件驱动,读取一行,解析一行.
如果XML文档比较大,DOM操作会造成内存溢出,但DOM操作可以对XML文件进行增删而SAX操作不能.
解析XML的API
常用的XML解析API有如下几种:jaxp, jdom,dom4j
其中dom4j应用最为广泛
Dom4j 基本用法
要解析XML文档,首先要把dom4j的jar包导入工程并添加路径.
解析如下XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<stus>
<stu id="1161160313">
<name>张三</name>
<age>18</age>
<address>深圳</address>
</stu>
<stu id="1161160314">
<name>李四</name>
<age>18</age>
<address>北京</address>
</stu>
</stus>
dom4j使用步骤:
- 创建SaxReader对象
- 指定XML源文件
- 获取根元素
- 根据根元素获取子元素或者下面的子孙元素
try {
// 1.创建sax读取对象
SAXReader reader = new SAXReader();
// 2.指定解析的xml源
Document document = reader.read(new File("src/xml/sts.xml"));
// 3.得到根元素
Element rootElement = document.getRootElement();
// 4.获取根元素下面的所有的子元素
List<Element> elements = rootElement.elements();
for (Element element : elements) {
// 获取stu子元素的name子元素
String name = element.element("name").getText();
String age = element.element("age").getText();
String address = element.element("address").getText();
System.out.println("name=" + name + ",age=" + age + ",address=" + address);
}
} catch (DocumentException e) {
e.printStackTrace();
}
Xpath语法
dom4j里支持Xpath语法. xpath是XML的路径语言,使我们在解析XML的时候,能够快速的定位到具体的某一个元素.
要想使用Xpath语法,要先引入对应的jar包.
Xpath常用语法:
/AAA/BBB/CCC
: 找到根元素下的AAA元素下的所有BBB子元素的所有CCC子元素.//AAA
: 找到文档中所有AAA元素.
try {
// 1.创建sax读取对象
SAXReader reader = new SAXReader();
// 2.指定解析的xml源
Document document = reader.read(new File("src/xml/sts.xml"));
// 3.得到根元素
Element rootElement = document.getRootElement();
// 4.根据xpath语法规则查找元素
// 使用selectSingleNode方法,只会返回第一个匹配的元素
Element nameElement= (Element)rootElement.selectSingleNode("//name");
System.out.println(nameElement.getText());
// 使用selectNodes方法,会返回所有匹配的元素
List<Element> nameElements= rootElement.selectNodes("//name");
for (Element element : nameElements) {
System.out.println(element.getText());
}
} catch (DocumentException e) {
e.printStackTrace();
}
XML约束
下面文档,属性的id值有相同,并且第二个学生有多个姓名元素. 这种情况在XML语法中是允许的,但不符合实际情况,因此要对其加以约束.
<stus>
<stu id="10086">
<name>张三</name>
<age>18</age>
<address>深圳</address>
</stu>
<stu id="10086">
<name>李四</name>
<name>李五</name>
<name>李六</name>
<age>28</age>
<address>北京</address>
</stu>
</stus>
对XML的语法有两种:DTD和SCHEMA,SCHEMA的出现是用来替代DTD的.