day23-xml解析
Posted teayear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了day23-xml解析相关的知识,希望对你有一定的参考价值。
day17_xml
一、课程目标
1. 【理解】什么是XML
2. 【掌握】XML的书写与组成
3. 【理解】XML约束
4. 【掌握】XML四种解析方式
二、XML概述
2.1 XML概念
Extensible Markup Language 可扩展标记语言
可扩展:标签都是自定义的。
2.2 XML作用
常用于存储数据和配置文件
最常用的功能就是xml做为一个配置文件
数据的传输–> 被json替代
2.3 XML基础语法
- xml文档的后缀名
.xml
- xml第一行必须定义为
文档声明
- xml文档中有且仅有一个
根标签
- 属性值必须使用
引号(单双都可)
引起来- 标签必须正确关闭
- xml标签名称
严格区分大小写
2.4 XML快速入门
<?xml version='1.0' ?>
<users>
<user id='1'>
<name>zhangsan</name>
<age>23</age>
<gender>male</gender>
<br/>
</user>
<user id='2'>
<name>lisi</name>
<age>24</age>
<gender>female</gender>
</user>
</users>
三、XML组成部分
3.1 文档声明
-
格式
<?xml 属性列表 ?>
-
属性列表
version
:版本号,必须的属性【1.0】encoding
:编码方式。告知解析引擎当前文档使用的字符集,默认值:ISO-8859-1standalone
:是否独立- 取值:
- yes:不依赖其他文件
- no:依赖其他文件
- 取值:
3.2 指令(了解)
<?xml-stylesheet type="text/css" href="a.css" ?>
3.3 标签
-
标签命名规则
- 名称可以包含字母、数字以及其他的字符
- 名称不能以数字或者标点符号开始
- 名称不能以字母 xml(或者 XML、Xml 等等)开始
- 名称不能包含空格
-
最佳命名习惯
-
名称应当比较简短,比如:<book_title>,而不是:<the_title_of_the_book>。
-
避免 “-” 字符。如果您按照这样的方式进行命名:“first-name”,一些软件会认为你需要提取第一个单词。
-
避免 “.” 字符。如果您按照这样的方式进行命名:“first.name”,一些软件会认为 “name” 是对象 “first” 的属性。
-
避免 “:” 字符。冒号会被转换为命名空间来使用(稍后介绍)。
-
XML 文档经常有一个对应的数据库,其中的字段会对应 XML 文档中的元素。有一个实用的经验,即使用数据库的名称规则来命名 XML 文档中的元素。
-
非英语的字母比如 éòá 也是合法的 XML 元素名,不过需要留意当软件开发商不支持这些字符时可能出现的问题。
-
3.4 属性
属性值必须被引号包围,不过单引号和双引号均可使用。比如一个人的性别,person 标签可以这样写:
<person sex="female">
或
<person sex='female'>
id属性
有时候会向元素分配 ID 引用。这些 ID 索引可用于标识 XML 元素.
<messages>
<note id="501">
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
<note id="502">
<to>John</to>
<from>George</from>
<heading>Re: Reminder</heading>
<body>I will not</body>
</note>
</messages>
注意事项
id属性值唯一
3.5 文本
CDATA区:在该区域中的数据会被原样展示
语法
<![CDATA[ 数据 ]]>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g8vKyCOr-1673935799606)(assets/image-20201213214748412-1649232873185.png)]
四、XML约束
一个良好的 XML 文档要满足以下规则:
- XML 文档必须有根元素
- XML 文档必须有关闭标签
- XML 标签对大小写敏感
- XML 元素必须被正确的嵌套
- XML 属性必须加引号
4.1 什么是约束
规定xml文档的书写规则
4.2 约束的使用
定义xml标签约束,使开发者按照定义书写,也可以约束html文件
4.3 约束的分类
4.3.1 DTD约束
document type definition 文档类型定义
4.3.1.1 DTD约束编写
扩展名是:dtd
<!ELEMENT students (student*) >
<!ELEMENT student (name,age,sex)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST student number ID #REQUIRED>
4.3.1.2 DTD约束引入
-
格式
* 内部dtd:将约束规则定义在xml文档中 * 外部dtd:将约束的规则定义在外部的dtd文件中 * 本地:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置"> * 网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件名字" "dtd文件的位置URL">
-
案例演示
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE students SYSTEM "student.dtd"> <students> <student number="D001"> <name>tom</name> <age>18</age> <sex>male</sex> </student> </students>
4.3.2 Schema约束
比dtd 更能更加强大。 提供了更加丰富的数据类型
XML Schema 可针对未来的需求进行扩展
XML Schema 更完善,功能更强大
XML Schema 基于 XML 编写 (schema本质上就是一个 xml文件)
XML Schema 支持数据类型 (提供的更加丰富的数据类型)
XML Schema 支持命名空间
4.3.2.1 Schema约束编写
扩展名是:xsd
<?xml version="1.0"?>
<xsd:schema xmlns="http://www.itfxp.com/xml"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itfxp.com/xml" elementFormDefault="qualified">
<xsd:element name="students" type="studentsType"/>
<xsd:complexType name="studentsType">
<xsd:sequence>
<xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="studentType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="age" type="ageType" />
<xsd:element name="sex" type="sexType" />
</xsd:sequence>
<xsd:attribute name="number" type="numberType" use="required"/>
</xsd:complexType>
<xsd:simpleType name="sexType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="male"/>
<xsd:enumeration value="female"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ageType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="256"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="numberType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="heima_\\d4"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
4.3.2.2 Schema约束引入
1.填写xml文档的根元素
2.引入xsi前缀. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3.引入xsd文件命名空间. xsi:schemaLocation="http://www.itfxp.com/xml student.xsd"
4.为每一个xsd约束声明一个前缀,作为标识 xmlns="http://www.itfxp.com/xml"
<?xml version="1.0" encoding="UTF-8" ?>
<!--
1.填写xml文档的根元素
2.引入xsi前缀. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3.引入xsd文件命名空间. xsi:schemaLocation="http://www.itfxp.com/xml student.xsd"
4.为每一个xsd约束声明一个前缀,作为标识 xmlns="http://www.itfxp.com/xml"
-->
<students
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itfxp.com/xml"
xsi:schemaLocation="http://www.itfxp.com/xml student.xsd">
<student number="Z0001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student>
</students>
五、XML解析
操作xml文档,将文档中的数据读取到内存中
5.1 操作XML两种情况
解析(读取):
将文档中的数据读取到内存中 【实际开发中,我们不做解析】
写入:
将内存中的数据保存到xml文档中。持久化的存储
5.2 常见解析XML方式
5.2.1 sax解析
(Simple API for XML)
处理方式类似于流处理,边读取边解析,采用的是事件回调的方式,书写好用于处理响应事件的方法,进行解析,当进行读取时触发相应事件,执行对应方法
优点:
进行解析时无需加载全部文档,可以边读取边解析
基于事件回调进行响应的解析,只有触发相应事件时才会回调相应方法
可以解析数据量大于内存的数据
缺点:
需要自己维护响应事件的回调方法,随文档的复杂度难度递增
单向解析,不会进行反向查询,只能从头解析
import java.io.InputStream;
import java.util.ArrayList;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
//sax解析xml
public class SaxParse
public static void main(String[] args) throws Exception
// 1、调用sax解析工厂对象newInstance方法创建sax解析工厂对象
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
// 2、调用sax工厂对象 newSAXParser方法创建sax解析对象
SAXParser saxParse = saxFactory.newSAXParser();
// 3、创建自定义解析器对象
MySaxHandler mh=new MySaxHandler();
// 4、使用解析对象传入自定义解析器与解析地址解析数据
InputStream is = SaxParse.class.getClassLoader().getResourceAsStream("com/yunhe/day0707/test.xml");
saxParse.parse(is, mh);
// 5、获取数据
ArrayList<Teacher> list = mh.list;
for (Teacher teacher : list)
System.out.println(teacher);
//sax需要自己创建解析器类解析对应的文件
//创建自定义解析器类继承默认的解析器类
//默认解析器类实现了方法但是没有书写任何方法体
class MySaxHandler extends DefaultHandler
//startElement
//当读取到起始标签时回调的方法
//endElement
//当读取到结束标签时回调的方法
//characters
//当读取到文本标签时回调的方法
//在sax解析中是按照标签进行解析
//起始标签 结束标签 文本标签
String str="";
//创建集合保存所有teacher对象数据
public ArrayList<Teacher> list=new ArrayList<>();
Teacher t;//保存每次读取数据的teacher对象
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
//当读取到teacher起始标识时创建teacher对象
if(qName.equals("teacher"))
t=new Teacher();
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
//当读取到teacher结束表情时将teacher对象加入集合
if(qName.equals("teacher"))
list.add(t);
else
//如果不是对象的结束标签
//判断是否是属性结束标签
if(qName.equals("name"))
t.setName(str);
else if(qName.equals("age"))
t.setAge(Integer.valueOf(str));
else if(qName.equals("sex"))
t.setSex(str);
@Override
public void characters(char[] ch, int start, int length) throws SAXException
str=new String(ch,start,length);
5.2.2 dom解析
(Document Object Model)
解析方式基于数据的节点层次结构进行解析,解析方式类可以理解为内嵌了处理器,在进行加载时使用已经提供的方式进行数据的解析,并以一定的层次结构进行保存,提供相应的方法可以直接进行数据的获取
dom解析采用的是默认处理器预处理形式进行解析,可以理解为执行时会先读取解析一遍数据,并将所有数据按照默认的格式进行存储
优点:
底层以数据节点的形式进行存储数据,提供相应的方法快速获取
可以对某一标签直接进行访问
缺点:
需要加载整个文件,消耗内存,不能处理大于内存的数据
无论是否需要都会加载整个数据
import java.io.InputStream;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
//dom解析xml
public class DomParse
public static void main(String[] args) throws Exception
//1、使用dom解析工厂类newInstance方法创建dom解析工厂对象
DocumentBuilderFactory DomFactory=DocumentBuilderFactory.newInstance();
//2、使用dom解析工厂对象newDocumentBuilder方法创建dom解析对象
DocumentBuilder domParse = DomFactory.newDocumentBuilder();
//3、使用dom解析对象方法解析指定的流,获取存储当前文档数据的Document对象
InputStream is = SaxParse.class.getClassLoader().getResourceAsStream("com/yunhe/day0707/test.xml");
Document dom = domParse.parse(is);
//4、调用Document类提供的方法从Document对象中获取指定数据
//通过标签名获取指定标签
//会方法当前xml中所有对应标签的对象数据
NodeList teacherList = dom.getElementsByTagName("teacher");
//NodeList 是其自定义的类似于集合的数据容器
ArrayList<Teacher> list=new ArrayList<>();//创建存储数据的集合
for (int i = 0; i < teacherList.getLength(); i++)
Teacher t=new Teacher();
//获取每个teacher标签
//item获取对应索引标签
Node teacher = teacherList.item(i);
//getChildNodes获取当前标签下的所有子标签
NodeList fieldList = teacher.getChildNodes();
for (int j = 0; j < fieldList.getLength(); j++)
//获取当前teacher标签中对应的属性标签
Node field = fieldList.item(j);
//获取当前属性标签对应数据以上是关于day23-xml解析的主要内容,如果未能解决你的问题,请参考以下文章