1. XML简介
- XML(Extensible Markup Language):可扩展标记语言
- XML与HTML的区别:
- XML标签都是自定义的,HTML标签是预定义
- XML的语法严格,HTML语法松散
- XML是存储数据,HTML是展示数据
- XML基本语法:
- XML文档的后缀名为.xml
- XML第一行必须定义为文档声明
- XML文档中有且仅有一个根标签
- 属性值必须使用引号(单双都可)引起来
- 标签必须正确关闭
- XML标签名称区分大小写
2. XML组成
-
文档声明
格式:<?xml 属性列表 ?> 属性列表: version:版本号,必须的属性 encoding:编码方式,告知解析引擎当前文档使用的字符集,默认值:ISO-8859-1 standalone:是否独立 =yes:不依赖其他文件 =no:依赖其他文件 结合css: <?xml-stylesheet type="text/css" href="css文件路径" ?>
-
元素(标签)
<标签名></标签名> <标签名/> 名称可以包含字母、数字以及其他的字符 名称不能以数字或者标点符号开始 名称不能以字母xml(或XML、Xml等)开始 名称不能包含空格
-
属性
id属性值唯一 属性定义格式:属性名=属性值 一个元素中不能出现同名属性 属性名不能使用空格、冒号等特殊字符,且必须以字母开头
-
CDATA区
CDATA区:在该区域中的数据会被原样展示 格式:<![CDATA[需要原样展示的数据]]>
-
注释
<!--注释内容-->
转义字符
3. 常见XML约束
- XML约束:编写一个文档来约束一个XML文档的书写规范
-
DTD(Document Type Definition):文档类型定义,规定XML文档中元素的名称,子元素的名称及顺序,元素的属性等。
引入dtd文档到xml文档中: 内部dtd:将约束规则定义在xml文档中 外部dtd:将约束的规则定义在外部的dtd文件中 本地:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置"> 网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件名字" "dtd文件的位置URL">
-
Schema,即XML Schema,XSD (XML Schema Definition)是许多XML Schema语言中的一支,扩展名为xsd,支持命名空间。
引入: 1. 填写xml文档的根元素 2. 引入xsi前缀 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3. 引入xsd文件命名空间 xsi:schemaLocation="给路径的别名 文件路径" 4. 为每一个xsd约束声明一个前缀作为标识 xmlns:标识="给路径的别名" 声明命名空间: 默认命名空间:<xxx xmlns=""> 使用:<标签> 显式命名空间:<xxx xmlns:别名=""> 使用:<别名:标签>
4. 常见XML解析方式
- DOM:将整个XML文档一次性加载进内存,在内存中形成一颗DOM树并获得一个Document对象,通过Document对象就可以对DOM进行操作。(可以对文档进行CRUD;占内存)
- SAX:是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件。(只能读取,不能增删改;不占内存)
- PULL:Android内置的XML解析方式,类似SAX。
5. 常见XML解析器
- 解析器:就是根据不同的解析方式提供的具体实现。有的解析器操作过于繁琐,为了方便开发人员,有提供易于操作的解析开发包。
5.1 dom4j
-
dom4j使用步骤:
- 导入支持XPath的jar包(如:dom4j-1.6.1.jar)
- 创建一个输入流,绑定待解析的XML文件
- 创建SAXReader对象,给其read方法传入输入流,以获取Document对象
- 使用Document对象的getRootElement()方法获取根标签Element
- 使用Element的方法elements获取根标签的子标签集合List<Element>
- 操作子标签集合中的子标签
-
SAXReader对象:
// 加载执行xml文档 public Document read(绑定了这个xml文件的输入流)
-
Document对象:
// 获得根元素 Element getRootElement()
-
Element对象
// 获得指定名称的所有子元素。可以不指定名称 List elements(...) // 获得指定名称第一个子元素。可以不指定名称 Element element(...) // 获得指定属性名的属性值 String attributeValue(...) // 获得指定名称子元素的文本值 String elementText(...) // 获得当前元素的文本内容 String getText() // 获得当前元素的元素名 String getName()
-
dom4j使用示例:
src下的student.xml文件内容: <?xml version="1.0" encoding="UTF-8" ?> <students> <student id="001"> <name>one</name> <age>10</age> <sex>male</sex> </student> <student id="002"> <name>two</name> <age>20</age> <sex>female</sex> </student> </students> dom4j使用示例: import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.io.InputStream; import java.util.List; public class Dom4jTest { public static void main(String[] args) throws DocumentException { // 1. 创建一个输入流,绑定待解析的XML文件 InputStream is = Dom4jTest.class.getClassLoader().getResourceAsStream("student.xml"); // 2. 创建SAXReader对象,给其read方法传入输入流,以获取Document对象 Document document = new SAXReader().read(is); // 3. 使用Document对象的getRootElement()方法获取根标签Element Element root = document.getRootElement(); // 4. 使用Element的方法elements获取根标签的子标签student的集合List<Element> List<Element> students = root.elements(); System.out.println("students.size(): " + students.size()); // 5. 操作子标签集合中的子标签student for (Element student : students) { // 获取student的子标签name、age、sex List<Element> studentSons = student.elements(); System.out.println("studentSons.size(): " + studentSons.size()); for (Element studentSon : studentSons) { System.out.println(studentSon.getName() + ": " + studentSon.getText()); } } /* 结果: students.size(): 2 studentSons.size(): 3 name: one age: 10 sex: male studentSons.size(): 3 name: two age: 20 sex: female */ } }
5.2 jsoup
jsoup是一款Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
-
jsoup使用步骤:
- 导入jar包(如:jsoup-1.11.2.jar)
- 使用Jsoup工具类获取XML文档的Document对象
- 根据Document对象获取指定标签的Elements集合
- 根据Elements集合获取标签的Element对象
- 根据Element对象获取标签的数据
-
Jsoup工具类:可以解析html或xml文档,返回Document
// 解析xml或html文件 static Document parse(File in, String charsetName) // 解析xml或html字符串 static Document parse(String html) // 通过网络路径获取指定的html或xml的文档对象 static Document parse(URL url, int timeoutMillis)
Document:文档对象,代表内存中的dom树;继承了Element
Elements:元素Element对象的集合,可以当做ArrayList<Element>来使用
-
Node:节点对象
// 根据属性名称获取属性值,不区分大小写 String attr(String attributeKey)
-
Element:元素对象;继承了Node
// 根据id属性值获取唯一的element对象 Element getElementById(String id) // 根据标签名称获取元素对象集合 Elements getElementsByTag(String tagName) // 根据属性名称获取元素对象集合 Elements getElementsByAttribute(String key) // 根据对应的属性名和属性值获取元素对象集合 Elements getElementsByAttributeValue(String key, String value) // 获取文本内容 String text() // 获取标签体的所有内容(包括子标签的标签和文本内容) String html() // 以该元素作为开始上下文,查找与选择器CSS查询匹配的元素 // 参考Selector类中定义的语法 Elements select(String cssQuery)
-
jsoup使用示例:
src下的student.xml文件内容: <?xml version="1.0" encoding="UTF-8" ?> <students> <student id="001"> <name>one</name> <age>10</age> <sex>male</sex> </student> <student id="002"> <name>two</name> <age>20</age> <sex>female</sex> </student> </students> jsoup使用示例: import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.File; import java.io.IOException; public class JsoupTest { public static void main(String[] args) throws IOException { // 获取XML文档路径 String path = JsoupTest.class.getClassLoader().getResource("student.xml").getPath(); // 1. 使用Jsoup工具类获取XML文档的Document对象 Document document = Jsoup.parse(new File(path), "utf-8"); // 2. 根据Document对象获取name标签的Elements集合 Elements names = document.getElementsByTag("name"); System.out.println("names.size(): " + names.size()); // 3. 根据Elements集合获取第一个name的Element对象 Element name0 = names.get(0); // 4. 根据Element对象获取第一个name的数据 System.out.println("name0.text(): " + name0.text()); /* 结果: names.size(): 2 name0.text(): one */ } }
6. XPath解析XML
XPath是一门在XML文档中查找信息的语言;可用来在XML文档中对元素和属性进行遍历
XPath语法查询参考:https://www.w3school.com.cn/xpath/index.asp
-
常用XPath表达式示例:
//book:选取所有book子元素,而不管它们在文档中的位置 bookstore:选取bookstore元素的所有子节点 /bookstore:选取根元素bookstore /*:获取所有元素 注:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! bookstore/book:选取属于bookstore的子元素的所有book元素 ele[n]:获取第n个ele标签 ele[last()]:获取最后一个ele标签 //ele[@att]:获取有att属性的ele标签 //ele[@att="val"]:获取有att属性值为val的ele标签
-
使用jsoup的XPath解析XML需要导入jar包(如:JsoupXpath-0.3.2.jar)
// 使用jsoup的XPath解析XML需要创建JXDocument(Document doc)对象 import cn.wanghaomiao.xpath.model.JXDocument; import cn.wanghaomiao.xpath.model.JXNode; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import java.io.File; import java.util.List; public class JsoupXPathTest { public static void main(String[] args) throws Exception { // 获取XML文档路径 String path = JsoupTest.class.getClassLoader().getResource("student.xml").getPath(); // 1. 使用Jsoup工具类获取XML文档的Document对象 Document document = Jsoup.parse(new File(path), "utf-8"); // 2. 将Document对象作为参数,创建JXDocument对象 JXDocument jxDocument = new JXDocument(document); // 3. 结合XPath语法查询 // 查询带有id属性值为001的student标签下的name标签 String xpath = "//student[@id='001']/name"; List<JXNode> jxNodes = jxDocument.selN(xpath); // 遍历查询到的标签 for (JXNode jxNode : jxNodes) { System.out.println(jxNode); } /* 结果: <name> one </name> */ } }
-
使用dom4j的XPath解析XML需要导入jar包(如:jaxen-1.1.6.jar)
使用dom4j的XPath解析XML需要用Element对象的方法: // 获取多个节点 List<Node> selectNodes("XPath表达式") // 获取遇到的第一个节点 Node selectSingleNode("XPath表达式")
若有错误或补充,欢迎私信