什么是XML

Extensible Markup Language 可扩展标记语言。主要用于存储数据。

基本语法

  1. xml文档的后缀名 .xml
  2. xml第一行必须定义为文档声明
  3. xml文档中有且仅有一个根标签
  4. 属性值必须使用引号引起来
  5. 标签必须正确关闭
  6. xml标签名称区分大小写
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8" ?>
<Persons>
<Person number="1">
<name>张三</name>
<age>17</age>
</Person>
<Person number="2">
<name>李四</name>
<age>18</age>
</Person>
</Persons>

标签的命名规则

  • 名称可以包含字母、数字以及其他的字符
  • 名称不能以数字或者标点符号开始
  • 名称不能以字母 xml(或者 XML、Xml 等等)开始
  • 名称不能包含空格

XML的特殊字符必须转义,通过CDATA可以保证数据原样输出。xml文档中的所有文本都会被解析器解析,只有CDATA区段中的文本会被解析器忽略。

  • 格式
1
2
3
<![CDATA[
原样输出的内容
]]>

XML的约束:规定XML文的书写规则

  • DTD(简单的约束)
    • 内部dtd :将约束定义在XML文档中

    • 外部dtd:将约束的规则定义在外部的dtd文件中
      本地:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
      网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件名字" "dtd文件的位置URL">

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8" ?>   
<!-- 内部 -->
<!DOCTYPE Persons [
<!ELEMENT Persons (Person*)>
<!ELEMENT Person (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ATTLIST Person number ID #REQUIRED>
]>
  • Schema(复杂的约束)

Schenma 约束XML数据具体类型,存储数据的类型严格按照Schema约束,否则报错。

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8" ?>
<students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.stranger-info.top/xml student.xsd"
xmlns="http://www.stranger-info.top/xml"
>
<student number="id_1">
<name>张三</name>
<age>18</age>
<sex></sex>
</student>
</students>

解析XML

操作XML文档,将文档中的数据读取到内存中,或者将内存中的数据写入保存到XML文档中,解析XML的方式主要有两种。

  • DOM
    一次性全部加载进内存,在内存中生成DOM树,所有内存消耗大,不适用内存小的设备,但是DOM操作方便。
  • SAX
    SAX通过事件驱动,逐行读取,读取完一行之后,进行释放,然后读取下一行。所有SAX不占用多少内存,不能对数据进行操作。

常见的XML解析器

  • JAXP
  • DOM4J
  • Jsoup
  • PULL

Jsoup使用

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) throws IOException {
//获取文档路径
String path = JsoupDemo01.class.getClassLoader().getResource("hello.xml").getPath();
//解析文档 获取 Document对象
Document document = Jsoup.parse(new File(path), "utf-8");
//获取元素对象
Elements elements = document.getElementsByTag("name");
//获取第一个name的Element对象
Element element = elements.get(0);
//获取数据
String text = element.text();
System.out.println(text);
}

Jsoup.parse ( )

1
2
3
parse(File in, String charsetName):解析xml或html文件的。
parse(String html):解析xml或html字符串
parse(URL url, int timeoutMillis):通过网络路径获取指定的html或xml的文档对象

Document 对象

1
2
3
4
getElementById(String id):根据id属性值获取唯一的element对象
getElementsByTag(String tagName):根据标签名称获取元素对象集合
getElementsByAttribute(String key):根据属性名称获取元素对象集合
getElementsByAttributeValue(String key, String value):根据对应的属性名和属性值获取元素对象集合

Elements:元素Element对象的集合。可以当做 ArrayList来使用

Element 元素对象

1
2
3
4
5
6
7
8
9
getElementById(String id):根据id属性值获取唯一的element对象
getElementsByTag(String tagName):根据标签名称获取元素对象集合
getElementsByAttribute(String key):根据属性名称获取元素对象集合
getElementsByAttributeValue(String key, String value):根据对应的属性名和属性值获取元素对象集合

String attr(String key):根据属性名称获取属性值

String text():获取文本内容
String html():获取标签体的所有内容(包括字标签的字符串内容)

selector 选择器使用

1
2
3
4
5
6
7
8
9
10
<persons>
<person number="id_1">
<name>张三</name>
<age>18</age>
</person>
<person number="id_2">
<name>李四</name>
<age>18</age>
</person>
</persons>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) throws IOException {
//获取文档路径
String path = JsoupDemo01.class.getClassLoader().getResource("hello.xml").getPath();
//解析文档 获取Document对象
Document document = Jsoup.parse(new File(path), "utf-8");
//获取Person标签并且number属性id_1的age子标签
Elements elements = document.select("person[number=\"id_1\"]>age");
System.out.println(elements);
/* 输出结果
<age>
17
</age>
*/
}

Xpath 选择器使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) throws IOException, XpathSyntaxErrorException {
//获取文档路径
String path = JsoupDemo01.class.getClassLoader().getResource("hello.xml").getPath();
//解析文档 获取Document对象
Document document = Jsoup.parse(new File(path), "UTF-8");
//创建JXDocument对象
JXDocument jxDocument=new JXDocument(document);
//查询所有person标签下的name标签
List<JXNode> jxNodes = jxDocument.selN("//person/name");
for(JXNode jxNode:jxNodes){
System.out.println(jxNode);
}
/*输出结果
<name>
张三
</name>
<name>
李四
</name>
*/

}

xpath : (“//标签名[ @属性= “属性值”]”)
具体查询参考文档

注意:如果XML文档标签首字母大写,则Xpath解析时的标签名小写,例如jxDocument.selN("//person")中的person必须小写,否则输出为空。(问题)