一、.XML
1、XML介绍
XML 指可扩展标记语言(Extensible Markup Language)
XML中没有预定义标签,所有的标签都是自己定义的。
XML是W3C组织的一个语言。
W3C在1988年2月发布XML1.0版本,我们现在用的就是1.0版本。在后面也有新的版本,但是新版本不太兼容旧版本,所以新版本没有被推广开。
2、编写XML
<天气预报>
<北京>
<东城区>
<最高温度>12℃</最高温度>
<最低温度>-2℃</最低温度>
</东城区>
<西城区>
<最高温度>13℃</最高温度>
<最低温度>-1℃</最低温度>
</西城区>
<顺义区>
<最高温度>14℃</最高温度>
<最低温度>-3℃</最低温度>
</顺义区>
</北京>
<天津>
<武清区>
<最高温度>15℃</最高温度>
<最低温度>2℃</最低温度>
</武清区>
<南开区>
<最高温度>20℃</最高温度>
<最低温度>6℃</最低温度>
</南开区>
</天津>
</天气预报>
3、XML的作用
- 可以传输数据,作为数据传输的载体
- 可以作为配置文件,保存配置信息
(properties用来存储一对一的键值对信息,xml用来存储有上下级关系的信息)
4、XML的组成部分
文档声明
<?xml version="1.0" encoding="UTF-8" ?>
注意事项:
- 文档声明必须以<?xml开头 , 必须以?>结尾
- 文档声明必须写在第一行第一列
- version表示版本,encoding表示编码
- 文档声明可以不写
元素
- 元素是XML中最重要的组成部分,元素也叫标签
- 标签分为开始标签和结束标签,开始标签<名字> 结束标签</名字>
- 开始标签和结束标签中间写的是标签内容,标签的内容可以是文本,也可以是其他标签
- 如果标签没有任何内容,那么可以定义为 自闭合标签(<名字/>)
- 命名规则: 不要使用XML xML xml 写样的单词,不能使用空格,冒号等特殊字符,命名区分大小写
- 一个XML文件有且仅有一个根标签
属性
- 属性是标签的一部分,属性必须写在开始标签或自闭合标签中,不能写在结束标签中
- 属性的书写格式:属性名=属性值,属性值必须使用单引号或双引号括起来,在XML中,单引和双引是没区别的。
- 一个元素可以有任意个属性,但是属性之间不能重名,多个属性之间用空格隔开
- 属性名不能使用特殊字符,必须以字母开头
注释
对代码的解释说明
<!-- 注释 -->
快捷键: ctrl+/ (是idea的注释快捷键,idea会自动识别语言匹配对应的注释)
转义字符
有些特殊的字符在XML中是会被识别的,比如<在XML中会被识别为标签,如果想要写这样的符号,需要用转义字符.
< <
> >
" "
<abc> 3 < 4 </abc>
CDATA区 (了解)
如果有大量的转义字符,可能就降低代码的阅读性,所以可以使用CDATA区去代替转义字符,在CDATA区中的文本不会被识别为特殊符号。
<!--CDATA区-->
<abc> <![CDATA[ <<<<<<<>>>>>>>> ]]> </abc>
二、XML文档的约束
1、概念
因为XML语言没有任何预定义标签,写任何标签都是可以的,这样导致解析比较困难复杂。
约束是对XML文件进行限制的,约束可以规定XML的标签内容和嵌套方式。
约束文件一定不会让我们自己写,但是今天理解一下约束的内容。
2、DTD约束
介绍
DTD约束写法简单,但是对XML的约束不是很严格,无法约束具体的数据类型。
DTD约束的文件后缀名.dtd
DTD约束文档
<!--
复制内容如下到XML文件中:
<!DOCTYPE 书架 SYSTEM "bookdtd.dtd">
-->
<!--Element表示元素,元素名称是书架,书架里书作为子元素-->
<!ELEMENT 书架 (书+)>
<!--书也是一个元素,书的子元素是书名,作者,售价-->
<!ELEMENT 书 (书名,作者,售价)>
<!--书名也是一个元素,#PCDATA表示书名里面是文本-->
<!ELEMENT 书名 (#PCDATA)>
<!--作者也是一个元素,#PCDATA表示作者里面是文本-->
<!ELEMENT 作者 (#PCDATA)>
<!--售价也是一个元素,#PCDATA表示售价里面是文本-->
<!ELEMENT 售价 (#PCDATA)>
DTD引入方式
1.内部DTD,在XML文档内部嵌入DTD,只对当前XML有效
<!DOCTYPE 根元素 [...//具体语法]>
2.外部DTD—本地DTD
<!DOCTYPE 根元素 SYSTEM "约束文件名称">
3.外部DTD—公共DTD
<!DOCTYPE 根标签 PUBLIC "dtd的名字" "网络上的位置">
xml需要使用DTD就要先引入dtd,但是这个代码一定不用我们写,一定是会提供的。
按照上面的dtd约束编写XML
<!DOCTYPE 书架 SYSTEM "bookdtd.dtd">
<书架>
<书>
<书名>java从入门到放弃</书名>
<作者>高斯林</作者>
<售价>99.8</售价>
</书>
</书架>
DTD约束的符号介绍
? :表示一个或零个
* :表示任意个
+ :表示一个或多个
, :表示按照顺序依次出现
| :表示或者
3、Schema约束
介绍
Schema约束能够对xml做出更严格的限制,可以对数据类型做精确的要求。
Schema约束的后缀名是.xsd
Schema约束文档
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 传智播客教学实例文档.将注释中的以下内容复制到要编写的xml的声明下面
复制内容如下到XML文件中:
<书架 xmlns="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn bookSchema.xsd" >
</书架>
-->
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn"
elementFormDefault="qualified">
<!--element表示元素 元素名是书架-->
<xs:element name='书架'>
<!--complextype表示书架是一个复杂标签(里面有子标签)-->
<xs:complexType>
<!--sequence表示顺序出现 maxOccurs表示最大出现次数-->
<xs:sequence maxOccurs="3" >
<!--书架的子标签是书-->
<xs:element name='书'>
<!--表示书也是一个复杂标签(里面有子标签)-->
<xs:complexType>
<!--书里面的子标签要顺序出现-->
<xs:sequence>
<!--书名是书的子标签 type表示类型-->
<xs:element name='书名' type='xs:string'/>
<!--作者是书的子标签 type表示类型-->
<xs:element name='作者' type='xs:string'/>
<!--售价是书的子标签 type表示类型-->
<xs:element name='售价' type='xs:double'/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
根据上面的Schema约束编写XML
<书架 xmlns="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn bookSchema.xsd" >
<书>
<书名>java入门当放弃</书名>
<作者>詹姆斯高斯林</作者>
<售价>99.8</售价>
</书>
<书>
<书名>java入门当放弃</书名>
<作者>詹姆斯高斯林</作者>
<售价>99.8</售价>
</书>
<书>
<书名>java入门当放弃</书名>
<作者>詹姆斯高斯林</作者>
<售价>99.8</售价>
</书>
</书架>
结论
不管是DTD还是Schema约束,约束文件是不会让你写的。
使用任何约束,都需要在XML中引入约束,引入的方式直接复制就可以了。
三、XML文件的DOM4J解析
1、解析方式
DOM:DOM方式的意思是把整个XML文件读取到内存中,然后解析其中的内容。
缺点:如果文件太大,可能导致内存不够用。
优点:可以对整个文档进行增删改查操作。
SAX: 读取一部分到内存中,解析完一部分之后释放内存再读取下一部分。
缺点:无法对整个文档进行增删改查操作。
优点:不占用大量内存,不会出现内存溢出。
2、解析开发包
JAXP: 这个工具是JDK中自带的解析开发包,用的时候不需要另外下载。
DOM4J: 这个开发包是第三方提供的,简单好用,如果使用需要下载jar包。
JSOUP: 这个开发包是用来解析HTML文件的,也可以用来解析XML,需要下载jar包。
百度网盘链接:https://pan.baidu.com/s/1z-0J0dZO-N2Et8E2NkT-8Q
提取码:1111
3、DOM4J解析
3.1 方法介绍
创建解析器对象:
SAXReader sr = new SAXReader();
解析器读取文件方法:
Document doc = sr.read(String fileName);
Document的方法:
getRootElement() : 获取根元素
节点中的方法:
elements() : 获取当前元素的子元素
element(String name) : 根据元素名获取指定子元素(如果有多个就获取到第一个)
getName() : 获取元素的元素名
attributeValue(String name) : 获取当前元素下某个属性的值
elementText(String name) : 获取指定子元素的文本值,参数是子元素名称
getText() : 获取当前元素的文本值
3.2 代码演示
XML文件
<天气预报>
<北京>
<东城区>
<最高温度>12℃</最高温度>
<最低温度>-2℃</最低温度>
</东城区>
<西城区>
<最高温度>13℃</最高温度>
<最低温度>-1℃</最低温度>
</西城区>
<顺义区>
<最高温度>14℃</最高温度>
<最低温度>-3℃</最低温度>
</顺义区>
</北京>
<天津 jc="津" level="1.5线">
<武清区>
<最高温度>15℃</最高温度>
<最低温度>2℃</最低温度>
</武清区>
<南开区>
<最高温度>20℃</最高温度>
<最低温度>6℃</最低温度>
</南开区>
</天津>
</天气预报>
java代码
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.List;
public class Test01 {
public static void main(String[] args) throws DocumentException {
//1.获取解析器对象
SAXReader reader = new SAXReader();
//2.读取文件
//Document叫文档
Document document = reader.read("day15\\tqyb.xml");
//获取根元素
Element rootE = document.getRootElement();
//elements() : 获取当前元素的子元素
List<Element> list = rootE.elements();
//遍历集合
for (Element element : list) {
System.out.println(element.getName());
}
System.out.println("=========================");
//element(String name) : 根据元素名获取指定子元素(如果有多个就获取到第一个)
Element e = rootE.element("天津");
System.out.println(e);
System.out.println("==========================");
//getName() : 获取元素的元素名
System.out.println(e.getName()); //天津
System.out.println("==========================");
//attributeValue(String name) : 获取当前元素下某个属性的值
String value = e.attributeValue("jc");
System.out.println(value); //津
String value2 = e.attributeValue("level");
System.out.println(value2); //1.5线
System.out.println("==========================");
//elementText(String name) : 获取指定子元素的文本值,参数是子元素名称
//通过‘天津’获取‘武清区’这个子元素
Element e2 = e.element("武清区");
//获取武清区最高温度的值
String s = e2.elementText("最高温度");
System.out.println(s); //15℃
System.out.println("==========================");
//getText() : 获取当前元素的文本值
Element e3 = e2.element("最高温度");
String s3 = e3.getText();
System.out.println(s3); //15℃
}
}
4、XPath演示
4.1 介绍
XPath是路径的表现形式,可以快速的定位XML中的元素。
Node中的两个方法可以使用XPath:
Node是XML中各种类型的父类,比如Node是Element的父类
List selectNodes("表达式") :使用Xpath作为参数查找多个元素
Node selectSingleNode("表达式") :使用Xpath作为参数查找某个元素(默认获取第一个)
4.2 Xpath表达式写法
-
绝对路径表达式方式
以/开始的路径叫绝对路径,绝对路径是根节点开始查询。
-
相对路径表达式方式
不以/开始的路径叫相对路径,相对路径是相对于当前节点。
-
全文搜索路径表达式方式
在路径中使用//表示全文搜索,也就是可以忽略中间的层级
-
谓语条件查询 (了解)
import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Node; import org.dom4j.io.SAXReader; import java.util.List; public class Test02 { public static void main(String[] args) throws DocumentException { //1.获取解析器对象 SAXReader reader = new SAXReader(); //2.读取文件 Document document = reader.read("day15\\tqyb.xml"); //Node表示结点,在XML中所有的类型都属于Node //Element是Node的子类 //Attribute是Node的子类 //List selectNodes("xpath表达式") :使用Xpath作为参数查找多个元素 //Node selectSingleNode("xpath表达式") :使用Xpath作为参数查找某个元素(默认获取第一个) //绝对路径: List<Node> list = document.selectNodes("/天气预报/北京/东城区"); //遍历集合 for (Node node : list) { System.out.println(node.getName()); } System.out.println("--------------------"); Node node = document.selectSingleNode("/天气预报/北京/东城区"); System.out.println(node.getName()); System.out.println("===================="); //相对路径 //通过东城区获取西城区 Node node1 = node.selectSingleNode("../西城区"); System.out.println(node1.getName()); //通过西城区获取武清区 Node node2 = node1.selectSingleNode("../../天津/武清区"); System.out.println(node2.getName()); System.out.println("==================="); //全文搜索 //获取所有的最高温度 List<Node> list2 = document.selectNodes("//最高温度"); for (Node node3 : list2) { System.out.println(node3.getText()); } System.out.println("-----------------"); //获取北京里面所有的最高温度 List<Node> list3 = document.selectNodes("//北京//最高温度"); for (Node node3 : list3) { System.out.println(node3.getText()); } System.out.println("-----------------"); //获取东城区的最高温度 Node node3 = document.selectSingleNode("//东城区//最高温度"); System.out.println(node3.getText()); //13℃ //谓语查询(条件查询) System.out.println("====================="); Node node4 = document.selectSingleNode("//最高温度[@level='a']"); System.out.println(node4.getText()); //15℃ } }
-
元素[@属性名=’属性值‘]
-