目录
XML
XML概述
XML是可扩展标记语言(eXtensible Markup Language)的缩写,它是是一种数据表示格式,可以描述非常复杂的数据结构,常用于传输和存储数据。文件后缀:.xml
XML的几个特点和使用场景
- 一是纯文本,默认使用UTF-8编码;
- 二是可嵌套; 如果把XML内容存为文件,那么它就是一个XML文件。
- XML的使用场景:XML内容经常被当成消息进行网络传输,或者作为配置文件用于存储系统的信息。
- 用于进行存储数据和传输数据、作为软件的配置文件
<!-- version:XML默认的版本号码、该属性是必须存在的encoding:本XML文件的编码 -->
<?xml version="1.0" encoding="UTF-8"?>
<data>
<sender>喜羊羊</sender>
<receiver>懒羊羊</receiver>
<src>
<addr>羊村</addr>
<date>2022-11-11 11:11:11</date>
</src>
<current>狼堡</current>
<dest>青青草原</dest>
</data>
XML的创建、语法规则
XML的创建
创建一个XML类型的文件,要求文件的后缀必须使用xml,如hello.xml
XML的语法规则
文档声明必须是第一行:<?xml version="1.0" encoding="UTF-8" ?>
- version:XML默认的版本号码、该属性是必须存在的
- encoding:本XML文件的编码
XML的标签(元素)规则
- 标签由一对尖括号和合法标识符组成: <name></name>,必须存在一个根标签,有且只能有一个。
- 标签必须成对出现,有开始,有结束: <name></name>
- 特殊的标签可以不成对,但是必须有结束标记,如:<br/>
- 标签中可以定义属性,属性和标签名空格隔开,属性值必须用引号引起来<student id = “1”></name>
- 标签需要正确的嵌套
XML的其他组成
- 定义注释信息:<!– 注释内容 -->
- 特殊字符
- < < 小于
- > > 大于
- & & 和号
- ' ' 单引号
- " " 引号
- 存在CDATA区: <![CDATA[ …内容… ]]> :可以写任何内容
<?xml version="1.0" encoding="UTF-8" ?>
<sheep>
<name>懒羊羊</name>
<age>3</age>
<sex>男</sex>
<hobby>睡觉</hobby>
<sql>
SELECT sheep FROM grassland WHERE age > 2;
<![CDATA[
SELECT sheep FROM grassland WHERE age > 2;
]]>
</sql>
</sheep>
XML文档约束方式一-DTD约束
问题:由于XML文件可以自定义标签,导致XML文件可以随意定义,程序在解析的时候可能出现问题。
文档约束:是用来限定xml文件中的标签以及属性应该怎么写。以此强制约束程序员必须按照文档约束的规定来编写xml文件
- 编写DTD约束文档,后缀必须是.dtd
- 在需要编写的XML文件中导入该DTD约束文档
- 按照约束的规定编写XML文件的内容。
- 可以约束XML文件的编写。
- 不能约束具体的数据类型。
<?xml version="1.0" encoding="UTF-8" ?>
</DOCTYPE 教室 SYSTEM "room.txt">
<!-- 把规范导入 -->
XML文档约束方式二-schema约束
可以约束XML文件的标签内容格式,以及具体的数据类型;本身也是xml文件,格式更严谨。
- 写schema约束文档,后缀必须是.xsd,具体的形式到代码中观看。
- 在需要编写的XML文件中导入该schema约束文档
- 按照约束内容编写XML文件的标签。
XML解析技术
XML解析技术概述
XML的数据的作用是存储数据、做配置信息、进行数据传输。 最终需要被程序进行读取,解析里面的信息
XML解析:使用程序读取XML中的数据
两种解析方式:SAX解析、DOM解析
Dom常见的解析工具
名称 | 说明 |
JAXP | SUN公司提供的一套XML的解析的API |
JDOM | JDOM是一个开源项目,它基于树型结构,利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作。 |
dom4j | 是JDOM的升级品,用来读写XML文件的。具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom 技术,同时它也是一个开放源代码的软件,Hibernate也用它来读写配置文件。 |
jsoup | 功能强大DOM方式的XML解析开发包,尤其对HTML解析更加方便 |
- Document对象:整个xml文档
- Element对象:标签
- Attribute对象:属性
- Text对象:文本内容
Dom4J解析XML文件 Dom4J
得到文档对象Document,从中获取元素对象和内容。
SAXReader类
构造器/方法 | 说明 |
public SAXReader() | 创建Dom4J的解析器对象 |
Document read(String url) | 加载XML文件成为Document对象 |
Document类
方法名 | 说明 |
Element getRootElement() | 获得根元素对象 |
Dom4j解析XML的元素、属性、文本
方法名 | 说明 |
List<Element> elements() | 得到当前元素下所有子元素 |
List<Element> elements(String name) | 得到当前元素下指定名字的子元素返回集合 |
Element element(String name) | 得到当前元素下指定名字的子元素,如果有很多名字相同的返回第一个 |
String getName() | 得到元素名字 |
String attributeValue(String name) | 通过属性名直接得到属性值 |
String elementText(子元素名) | 得到指定名称的子元素的文本 |
String getText() | 得到文本 |
<?xml version="1.0" encoding="UTF-8" ?>
<sheep>
<name id = "1">懒羊羊</name>
<age>3</age>
<sex>男</sex>
<hobby>睡觉</hobby>
<sql>
SELECT sheep FROM grassland WHERE age > 2;
<![CDATA[
SELECT sheep FROM grassland WHERE age > 2;
]]>
</sql>
</sheep>
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.SAXValidator;
import org.junit.Test;
import java.io.File;
import java.io.InputStream;
import java.util.List;
public class Dom4jTest1 {
@Test
public void parseXMLData() throws Exception {
//1、创建一个Dom4j的解析器对象,代表了整个dom4j框架
SAXReader saxReader = new SAXReader();
// 2、把XML文件加载到内存中成为一个Document文档对象
//Document document = saxReader.read(new File("demo5_XML/src/hello.xml"));
//getResourceAsStream中的/是直接去src下寻找的文件
InputStream is = Dom4jTest1.class.getResourceAsStream("/hello.xml");
Document document = saxReader.read(is);
// 获取根元素对象
Element root = document.getRootElement();
System.out.println(root.getName()); //根元素名字
List<Element> elementList = root.elements(); //获取所有一级子元素
//遍历
for(Element element : elementList) {
System.out.println(element.getName()+" "+element.getTextTrim());
//getText---不去空格 getTextTrim---去空格
}
//属性
Element element = root.element("name");
System.out.println(element.attribute("id").getName()+"-->"+element.attributeValue("id"));
}
}
XML检索技术:Xpath
- Dom4j需要进行文件的全部解析,然后再寻找数据。
- Xpath技术更加适合做信息检索。Xpath技术依赖Dom4j技术
XPath在解析XML文档方面提供了一独树一帜的路径思想,更加优雅,高效 XPath使用路径表达式来定位XML文档中的元素节点或属性节点。
- /元素/子元素/孙元素/孙孙元素
Xpath作用:
<!-- hello2.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<sheep>
<name id = "1">懒羊羊</name>
<age>3</age>
<sex>男</sex>
<hobby>睡觉</hobby>
<info>
<name id = "2">小懒羊</name>
<name id = "3">懒小羊</name>
<hobby>吃草</hobby>
<hobby>吃冰淇淋</hobby>
</info>
<sql>
SELECT sheep FROM grassland WHERE age > 2;
<![CDATA[
SELECT sheep FROM grassland WHERE age > 2;
]]>
</sql>
</sheep>
- 检索XML文件中的信息 绝对路径: /根元素/子元素/孙元素
方法名 | 说明 |
/根元素/子元素/孙元素 | 从根元素开始,一级一级向下查找,不能跨级 |
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.List;
//绝对路径
public class XpathTest3 {
@Test
public void parse01() throws Exception {
//1.创建解析器对象
SAXReader saxReader = new SAXReader();
//2.把XML加载成Document文档对象
Document document = saxReader.read(XpathTest3.class.getResourceAsStream("/hello2.xml"));
//3.检索全部的名称
List<Node> nameNodes = document.selectNodes("/sheep/info/name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element) nameNode;
System.out.println(nameEle.getTextTrim());
}
}
}
- 相对路径:./子元素/孙元素
方法名 | 说明 |
./子元素/孙元素 | 从当前元素开始,一级一级向下查找,不能跨级 |
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.List;
//相对路径
public class XpathTest3 {
@Test
public void parse02() throws Exception {
//1.创建解析器对象
SAXReader saxReader = new SAXReader();
//2.把XML加载成Document文档对象
Document document = saxReader.read(XpathTest3.class.getResourceAsStream("/hello2.xml"));
Element root = document.getRootElement();
//3.检索全部的名称
List<Node> hobbyNodes = root.selectNodes("./info/hobby"); //.代表了当前元素
for (Node hobbyNode : hobbyNodes) {
Element nameEle = (Element) hobbyNode;
System.out.println(nameEle.getTextTrim());
}
}
}
- 全文检索://contact
方法名 | 说明 |
//contact | 找contact元素,无论元素在哪里 |
//contact/name | 找contact,无论在哪一级,但name一定是contact的子节点 |
//contact//name | contact无论在哪一种,name只要是contact的子孙元素都可以找到 |
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.List;
public class XpathTest3 {
@Test
public void parse03() throws Exception {
//1.创建解析器对象
SAXReader saxReader = new SAXReader();
//2.把XML加载成Document文档对象
Document document = saxReader.read(XpathTest3.class.getResourceAsStream("/hello2.xml"));
//3.检索数据
List<Node> nameNodes = document.selectNodes("//name");
List<Node> hobbyNodes = document.selectNodes("//info//hobby");
for (Node nameNode : nameNodes) {
Element nameEle = (Element) nameNode;
System.out.println(nameEle.getTextTrim());
}
for (Node hobbyNode : hobbyNodes) {
Element nameEle = (Element) hobbyNode;
System.out.println(nameEle.getTextTrim());
}
}
}
- 属性查找://@属性名 、//元素[@属性名]、//元素//[@属性名=‘值’]
方法名 | 说明 |
//@属性名 | 查找属性对象,无论是哪个元素,只要有这个属性即可。 |
//元素[@属性名] | 查找元素对象,全文搜索指定元素名和属性名。 |
//元素//[@属性名=‘值’] | 查找元素对象,全文搜索指定元素名和属性名,并且属性值相等。 |
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.List;
public class XpathTest3 {
@Test
public void parse04() throws Exception {
//1.创建解析器对象
SAXReader saxReader = new SAXReader();
//2.把XML加载成Document文档对象
Document document = saxReader.read(XpathTest3.class.getResourceAsStream("/hello2.xml"));
//3.检索数据
List<Node> nodes = document.selectNodes("//name[@id]");
for (Node node : nodes) {
Element ele = (Element) node;
System.out.println(ele.getTextTrim() + "--->" + ele.attributeValue("id"));
}
// 查询name元素(包含id属性的)
Node node = document.selectSingleNode("//name[@id=1]");
Element ele = (Element) node;
System.out.println(ele.getTextTrim());
}
}