day23-xml解析

Posted 云和数据张老师

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基础语法

  1. xml文档的后缀名 .xml
  2. xml第一行必须定义为文档声明
  3. xml文档中有且仅有一个根标签
  4. 属性值必须使用引号(单双都可)引起来
  5. 标签必须正确关闭
  6. 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-1
    • standalone:是否独立
      • 取值:
        • 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解析的主要内容,如果未能解决你的问题,请参考以下文章

day23-xml解析

day23-xml解析

day23-xml解析

XML的XmlPullParser解析

day02-解析器

Day01—xml的序列化xml的pull解析