XML
1.XML介绍与用途
1.1 XML是什么?
-
XML全称是EXtensible Markup Language,可扩展性标记语言。
-
编写XML就是编写标签,与HTML非常类似,扩展名.xml。
-
良好的人机可读性。
例:hr.xml
<employee>
<name>张三</name>
<age>31</age>
<height>178</height>
</employee>
1.2 XML与HTML的比较
- XML与HTML非常相似,都是编写标签。
- XML没有预定义标签,HTML存在大量预定义标签。
- XML重在保存与传输数据,HTML用于显示信息。
1.3 XML的用途
-
Java程序的配置描述文件。
例:web应用配置文件
<web-app> <servlet> <servlet-name>XXXXX</servlet-name> <servlet-class>XXXX</servlet-class> <init-param> <param-name>1</param-name> <param-value>1</param-value> </init-param> <init-param> <param-name>2</param-name> <param-value>2</param-value> </init-param> </servlet> </web-app>
-
用于保存程序产生的数据。
例:hr.xml
<employee> <name>张三</name> <age>31</age> <height>178</height> <salary>7800</salary> </employee> <employee> <name>李四</name> <age>25</age> <height>168</height> <salary>5800</salary> </employee>
-
网络间的数据传输。
例:webservice底层soap协议:
<Envelope>
<Body>
<m:reversexmlns:m="urn:strings-com:lString">
<theString>Hello,World</theString>
</m:reversexmlns>
</Body>
</Envelope>
利用XML进行请求和响应的打包和解析的处理。
2.XML的语法规则
2.1 XML文档结构
- 第一行必须是XML声明。
XML声明说明XML文档的基本信息,包括版本号与字符集,写在XML第一行。
例:
<?xml version="1.0" encoding="UTF-8"?>
version 代表版本号1.0/1.1(常用1.0版本)。
encoding UTF-8设置字符集,用于支持中文 。
- 有且只有一个根节点。
例:hr.mxl
<?xml version="1.0" encoding="UTF-8"?>
<hr>
<employee>
<name>张三</name>
<age>31</age>
<salary>5000</salary>
<department>
<dname>会计部</dname>
<address>xx大厦</address>
</department>
</employee>
.....
</hr>
可以将XML拖入浏览器中,如果正常显示,表示语法没有问题,也可以用IDEA进行校验。
- XML标签的书写规则与HTML相同。
2.2 XML标签书写规则
2.2.1 合法的标签名
- 标签名要有意义。
- 建议使用英文,小写字母,单词之间使用“-”(减号)分割。
- 建议多级标签中间不要存在重名的情况。
错误案例:
<abc>abc</abc> -->标签无实际意义
<考试$>数学期末</考试$> -->不推荐标签使用中文
<class><class>班级</class></class> -->父标签和子标签最好不要重名。
正确示范:
<shop-cart><item>相册</item></shop-cart>
2.2.2 适当的缩进和注释
目的:为了让XML文档有更好的阅读性。
错误示范:
<employee><name>张三</name><age>31</age><salary>5000</salary</employee>
正确示范
<!--员工信息--><employee> <name>张三</name> <age>31</age> <salary>5000</salary></employee>
2.2.3 合理使用属性
- 标签属性用于描述标签不可或缺的信息
- 对标签分组或者为标签设置id时常用属性表示。
- 把“对象”唯一的特征如“id”、序列号等身份信息放在属性中。
2.2.4 特殊字符与CDATA标签的使用
- 标签体中,出现“<”、">"特殊字符,会破坏文档结构。
例:无效的XML
<exam> <question>1+4<3是否正确?</question></exam>
解决办法:
1.使用实体引用。
实体引用 | 对应符号 | 说明 |
---|---|---|
<; | < | 小于 |
>; | > | 大于 |
&; | & | 和号 |
&apos; | ’ | 单引号 |
"; | " | 双引号 |
修改后的案例:
<exam> <question>1+4<3是否正确?</question></exam>
适合文档中少量的特殊符号的引用,如果有大量的符号的话可以使用CDATA标签的方式进行转换。
2.使用CDATA标签。
- CDATA指的是不应由XML解析器进行解析的文本数据。
- 语法:从<![CDATA[“开始位置,结束位置”]]"结束,系统不再对XML进行解析,直接输出原文本。
2.2.5 有序地子元素
- 在XML多层嵌套的子元素中,标签前后顺序应保持一致 。这是作为软件工程师的职业素质。
3.XML的语义约束
- XML文档结构正确,但可能不是有效的。
比如:员工XML中出现“植物品种标签”。
- XML语义约束就是用于规定XML文档中允许出现那些元素。
- XML语义约束有两种定义方式:DTD与XML Schema.
3.1 DTD
- DTD(Document Type Definition,文档类型定义)是一种简单易用的语义约束方式。
- DTD文件的扩展名为.dtd。
3.1.1 DTD定义节点
- 利用DTD中的<!ELEMENT>标签,我们可以定义XML文档中允许出现的节点及数量。
- 定义 节点下 只允许出现1个 employee 子节点:
<! ELEMENT hr (employee) >
2.employee 节点下必须包含以下四个节点,且按顺序出现。
<!ELEMENT employee (name , age , salary ,department)>
3.定义name 标签只能是文本 ,#PCDATA 代表文本元素。
<!ELEMENT name (#PCDATA)>
3.1.2 定义节点数量:
增加节点描述符:
<!ELEMENT hr (employee+)>
“+”:最少一个节点。
“*”:0个或者多个节点。
“?”: 最多出现一个节点。
3.1.3 XML引用DTD文件
- 在XML中使用<!DOCTYPE> 标签来引用DTD文件。
书写格式:
<!DOCTYPE 根节点 SYSTEM “dtd文件路径”>
示例:
<!DOCTYPE hr SYSTEM "hr.dtd">
SYSTEM 表示加载本地的文件,hr.dtd表示加载相同目录下的hr.dtd文件。
- 完成XML与DTD文件的绑定!
3.1.4 DTD文件的创建与使用
创建DTD文件,在XML文件中引用,引用之后会对XML的编写进行校验,判断是否满足DTD文件中的要求!
3.2 XML Schema
- XML Schema比DTD更为复杂,提供了更多功能。
- XML Schema 提供了数据类型、格式限定、数据范围等特性
- XML Schema是W3C标准
在早期,大多是DTD文档进行约束的,现在基本上使用Schema进行约束了。
使用方式:
1.创建XML Schema 文件后缀是“.xsd”。
2.编写Schema文档,在XML文件中进行引用。
例:hr.xsd
<?xml version="1.0" encoding="UTF-8"?><schema xmlns="http://www.w3.org/2001/XMLSchema"> <element name="hr"> <!-- complexType标签含义是复杂节点,包含子节点时必须使用这个标签 --> <complexType> <sequence> <element name="employee" minOccurs="1" maxOccurs="9999"> <complexType> <sequence> <element name="name" type="string"></element> <element name="age"> <simpleType> <restriction base="integer"> <minInclusive value="18"></minInclusive> <maxInclusive value="60"></maxInclusive> </restriction> </simpleType> </element> <element name="salary" type="integer"></element> <element name="department"> <complexType> <sequence> <element name="dname" type="string"></element> <element name="address" type="string"></element> </sequence> </complexType> </element> </sequence> <attribute name="no" type="string" use="required"></attribute> </complexType> </element> </sequence> </complexType> </element> </schema>
XML Schema中的标签:
【compexType:复杂节点后面跟sequence标签】
【simpleType:简单类型】
【element:元素节点】
【attribute: 定义属性】
【minOccurs=“1”:最少出现一次】
【maxOccurs=“999”:最多出现999次】
hr.xml:
<?xml version="1.0" encoding="UTF-8"?><!-- 人力资源管理系统 --><hr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="hr.xsd"> <employee no="3309"> <name>张三</name> <age>31</age> <salary>4000</salary> <department> <dname>会计部</dname> <address>XX大厦-B103</address> </department> </employee> <employee no="3310"> <name>李四</name> <age>23</age> <salary>3000</salary> <department> <dname>工程部</dname> <address>XX大厦-B104</address> </department> </employee></hr>
绑定xml,hr.xsd为指定文件
<hr xmlns:xsi = "http://www.w3c.org/2001/XMLSchema-instance"> xsi:noNamespaceSchemaLocation="hr.xsd"
4.JAVA解析XML
4.1 DOM文档对象模型
- DOM(Document Object Model)定义了访问和操作XML文档的标准方法,DOM把XML文档作为树结构来查看,能够通过DOM树来读写所有元素。
例:
<Cart> <item sn="771938"> <name>XX空调</name> <price>2000.00</price> </item> <item sn="890321"> <name>法式面包</name> <price>10.00</price> </item></Cart>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u8ZOZkyj-1628774578384)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210812202043240.png)]
4.2 Dom4j
- Dom4j是一个易用的、开源的库,用于解析XML。它应用于Java平台,具有性能优异、功能强大和极其易用的特点。
- Dom4j将XML是为Document对象。
- XML标签被Dom4j定义为Element对象。
4.2.1 使用Dom4j的方法:
1.下载Dom4j的JAR包进行导入并加载(Maven可直接进行引入)。
2.创建JAVA类,命名xxReader即可,对XML进行读取。
例:以上面的hr.xml
package com.imooc.dom4j;import java.util.Iterator;import java.util.List;import org.dom4j.Attribute;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;public class HrReader { public HrReader() { } public void readXml() { String file = "d:/workspace/xml/src/hr.xml"; //SAXReader类是读取XML文件的核心类,用于将XML解析后以“树”的形式保存在内存中 SAXReader reader = new SAXReader(); try { Document document = reader.read(file); //获取XML文档的根节点,即HR标签 Element root = document.getRootElement(); //elements方法用于获取指定的标签集合 List<Element> employees = root.elements("employee"); //遍历XML文档中的内容 for(Elenment employee:employees){ Element name = employee.element("name"); String empName = name.getText();//getText()方法用于获取标签文本。 System.out.println(empName); System.out.println(employee.elementText("age")); System.out.println(employee.elementText("salary")); Element department = employee.element("department"); System.out.println(department.element("dname").getText()); System.out.println(department.element("address").getText()); Attribute att = employee.attribute("no"); System.out.println(att.getText()); } } catch (DocumentException e) { e.printStackTrace(); } }}
- 利用Dom4j更新XML
package com.imooc.dom4j;import java.io.FileOutputStream;import java.io.OutputStreamWriter;import java.io.Writer;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader; public void writeXml() { String file = "d:/workspace/xml/src/hr.xml"; SAXReader reader = new SAXReader(); try { Document document = reader.read(file); Element root = document.getRootElement(); Element employee = root.addElement("employee"); employee.addAttribute("no", "3311"); Element name = employee.addElement("name"); name.setText("李铁柱"); employee.addElement("age").setText("37"); employee.addElement("salary").setText("3600"); Element department = employee.addElement("department"); department.addElement("dname").setText("人事部"); department.addElement("address").setText("XX大厦-B105"); Writer writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); document.write(writer); writer.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { HrWriter hrWriter = new HrWriter(); hrWriter.writeXml(); }}
在编写dom4j本身不会对dtd或Scame进行校验的。建议每次写完要进行检查!
5.XPath路径表达式
-
XPath路径表达式XPath路径表达式是XML文档中查找数据的语言
-
掌握XPath可以极大的提高在提取数据时的开发效率
-
学习XPath本质就是掌握各种形式表达式的使用技巧
5.1XPath基本表达式
-
最常见的基本表达式
nodename(节点名称):读取此节点的所有子节点
/ :从根节点获取
// :从匹配选择的当前节点选择文档中的节点,二不考虑它的位置
. :读取当前节点
… :读取当前节点的父节点
@ :选取属性
nodename | 读取此节点的所有子节点 |
---|---|
/ | 从根节点获取 |
// | 从匹配选择的当前节点选择文档中的节点,二不考虑它的位置 |
. | 读取当前节点 |
… | 读取当前节点的父节点 |
@ | 选取属性 |
XPath基本表达式案例:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hHmcLZGQ-1628774578433)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210812210504834.png)]
XPath谓语表达式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rAWNsvG7-1628774578437)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210812210713551.png)]
5.2 XPath实验室
package com.imooc.dom4j;import java.util.Iterator;import java.util.List;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.Node;import org.dom4j.io.SAXReader;public class XPathTestor { public XPathTestor() { } public void xpath(String xpathExp) { //导入需要读取的XML文件 String file = "E:/lianxi/xml/hr.xml"; SAXReader reader = new SAXReader(); try { Document document = reader.read(file); List<Node> nodes = document.selectNodes(xpathExp); //遍历器进行遍历 Iterator it = nodes.iterator(); while(it.hasNext()) { Node node = (Node)it.next(); Element emp = (Element)node; System.out.println(emp.attributeValue("no")); System.out.println(emp.elementText("name")); System.out.println(emp.elementText("age")); System.out.println(emp.elementText("salary")); System.out.println("=============================="); } } catch (DocumentException var9) { var9.printStackTrace(); } } public static void main(String[] args) { XPathTestor testor = new XPathTestor(); //根据不同的节点进行查询 testor.xpath("//employee[3] | //employee[8]");//支持组合表达式 testor.xpath("/hr/employee); ······ }}