MySql的初学习 -- 第十八章 -- XML

本文详细介绍了XML的基本概念、语法、自定义描述数据的方式以及XML的约束,包括DTD和Schema。此外,还探讨了XML解析,如DOM4J解析器和XPath的使用,包括它们的API和导入方法。


博客说明

文章内容输出来源:拉勾教育Java就业急训营

什么是XML

XML即可扩展标记语言(Extensible Markup Language)
XML可以存储数据、做为配置文件、在网络中传输,不过目前最常用的还是做为配置文件
特点:

  1. 可扩展的, 标签都是自定义的
  2. 语法十分严格

XML的语法

<?xml version="1.0" encoding="UTF_8"?>
<!-- XML的注释      👆
    1.XML中必须进行文档声明
        version:版本信息
        encoding:编码
    2.xml的文档声明必须写在第一行
    3.xml的元素标签命名规则
    	标签定义,不能使用空格 或者冒号
    	xml标签名称区分大小写
    4.xml中 有且只有一个根元素
    5.元素体  可以是文本 或者 是一个标签
    6.属性是元素的一部分 只能出现在元素的开始标签中
      属性值必须使用单引号或者双引号包裹
      一个元素标签可以定义多个属性   
    ->

<!-- 根元素名称不能重复,子元素可以 -->
<users>  
	<!-- 这里id为属性,只能出现在开始标签中 -->
	<user id="no1">
		<name>张三</name>
	</user>
	
	<user id="no2">
		<name></name>
		<age></age>
	</user>
	
	<close/>  <!-- 空元素,没有结束标签 -->
</users>

自定义xml描述数据

<?xml version="1.0" encoding="UTF-8" ?>
<employees>
    <employee eid="2">
        <ename>关羽</ename><!-- 姓名 -->
        <age>20</age><!-- 年龄 -->
        <sex></sex><!-- 性别 -->
    </employee>

    <employee eid="3">
        <ename>张飞</ename>
        <age>18</age>
        <sex></sex>
    </employee>
<!-- 标签与标签之间的称为文本内容 -->
</employees>

XML约束

  1. XML约束:XML标签书写规范
  2. XML的约束由各框架提供,学习阶段只要求:会阅读、会引入即可,不用自己编写XML约束
  3. 常见的XML约束格式有:DTD、Schema

DTD约束

常见框架使用DTD约束有: Struts2、hibernate等

<!ELEMENT students (student+) >
        <!ELEMENT student (name,age,sex)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT age (#PCDATA)>
        <!ELEMENT sex (#PCDATA)>
        <!ATTLIST student number ID #REQUIRED>

<!--
    ELEMENT : 定义元素
    students (student+) : students 代表根元素
                           student+  代表根元素标签中至少有一个 student子元素
    student (name,age,sex):student标签中可以包含子元素,按顺序出现
    #PCDATA:普通的文本内容
    ATTLIST:用来定义属性
    student number ID:student标签中,有一个ID属性 叫做name
    #REQUIRED:number属性必须填写
    ID:唯一的值,不能重复,值只能是字母或者下划线开头
-->

DTD约束的引入

  1. 内部dtd:将约束规则定义在xml文档中
  2. 外部dtd:将约束的规则定义在外部的dtd文件中
    外部dtd
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "student.dtd">  <!-- DTD文件导入 -->
<students>
	<!-- 下面student会自动生成,所写的标签只能为约束中定义好的,不能随便改,会报错 -->
    <student number="s1">
        <name>刘备</name>
        <age>30</age>
        <sex></sex>
    </student>
    <student number="s2">
        <name>关羽</name>
        <age>20</age>
        <sex></sex>
    </student>
</students>

Schema约束

什么是Schema约束

  1. Schema是新的XML文档约束, 比DTD强大很多,是DTD 替代者;
  2. Schema本身也是XML文档,但Schema文档的扩展名为xsd,而不是xml。
  3. Schema 功能更强大,内置多种简单和复杂的数据类型
  4. Schema 支持命名空间 (一个XML中可以引入多个约束文档)

Schema导入

准备一个Schema文件

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://www.xxx.com/xml"  <!-- 文档的命名空间,可自定义 -->
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" <!-- Schema自带的命名空间 -->
            targetNamespace="http://www.xxx.com/xml" <!-- 文档定义的元素来自于哪一个命名空间 -->
            elementFormDefault="qualified">
            <!-- 
            elementFormDefault属性:
			非全局的元素当设置为qualified时,必须添加命名空间的前缀。
			非全局的元素当设置为unqualified时,不必也不能添加前缀。
			-->
			
			<xsd:element name="students" type="studentsType"/><!-- 根元素 -->
</xsd:schema>
  1. 查看schema文档,找到根元素,在xml中写出来
<?xml version="1.0" encoding="UTF-8" ?>
<students> 
</students>
  1. 根元素来自哪个命名空间。使用xmlns指令来声明
<?xml version="1.0" encoding="UTF-8" ?>
<students
   xmlns="http://www.xxx.com/xml" >
</students>
  1. 引入 w3c的标准命名空间, 复制即可
<?xml version="1.0" encoding="UTF-8" ?>
<students
   xmlns="http://www.xxx.com/xml"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
</students>
  1. 引入的命名空间跟哪个xsd文件对应?
    使用schemaLocation来指定:两个取值:第一个为命名空间 第二个为xsd文件的路径
<?xml version="1.0" encoding="UTF-8" ?>
<students
   xmlns="http://www.xxx.com/xml"        
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.xxx.com/xml student.xsd" >
</students>

XML解析

开发中比较常见的解析方式有两种,如下:

  1. DOM:要求解析器把整个XML文档装载到内存,并解析成一个Document对象。
    优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
    缺点:XML文档过大,可能出现内存溢出显现。
  2. SAX:是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方 式进行具体解析,每执行一行,都将触发对应的事件。(了解)
    优点:占用内存少 处理速度快,可以处理大文件
    缺点:只能读,逐行后将释放资源。

常见的XML解析器

为什么使用解析器:XML解析方式只是一个思想,需要实现具体功能则需要用到解析器

  1. JAXP:sun公司提供的解析器,支持DOM和SAX两种思想
  2. DOM4J:一款非常优秀的解析器 , Dom4j是一个易用的、开源的库,用于XML,XPath和XSLT。 它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。
  3. Jsoup:jsoup 是一款Java 的HTML解析器 ,也可以解析XML
  4. PULL:Android内置的XML解析方式,类似SAX。

DOM4J解析器的使用

导入DOM4J

  1. 导入JAR包
    导入JAR包
    关于导入详细信息(按照JBDC安装即可)👈点这里

DOM4J的API介绍

DOM4J解析器核心类SaxReader加载xml文档获得Document,通过Document 对象获得文档的根元素,然后就 可以操作了

SaxReader对象:

方法描述
read(…)加载执行xml文档

Document对象:

方法描述
getRootElement()获得根元素

Element对象:

方法描述
elements(…)获得指定名称的所有子元素。可以不指定名称
element(…)获得指定名称的第一个子元素。可以不指定名称
getName()获得当前元素的元素名
attributeValue(…)获得指定属性名的属性值
elementText(…)获得指定名称子元素的文本值
getText()获得当前元素的文本内容

使用DOM4J解析XML

  1. 准备一个合格的XML(需要有约束的XML,推荐使用Schema约束)
    user.xsd
    👇
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://www.xxx.com/xml"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.xxx.com/xml"
            elementFormDefault="qualified">
    <xsd:element name="users" type="usersType"/>
    <xsd:complexType name="usersType">
        <xsd:sequence>
            <xsd:element name="user" type="userType" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="userType">
        <xsd:sequence>
            <xsd:element name="name" type="xsd:string"/>
            <xsd:element name="age" type="ageType" />
            <xsd:element name="hobby" type="hobbyType" />
        </xsd:sequence>
        <xsd:attribute name="id" type="numberType" use="required"/>
    </xsd:complexType>
    <xsd:simpleType name="ageType">
        <xsd:restriction base="xsd:integer">
            <xsd:minInclusive value="0"/>
            <xsd:maxInclusive value="100"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="hobbyType">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="抽烟"/>
            <xsd:enumeration value="喝酒"/>
            <xsd:enumeration value="烫头"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="numberType">
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="\d{4}"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

user.xml
👇

<?xml version="1.0" encoding="UTF-8" ?>
<users  xmlns="http://www.xxx.com/xml"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.xxx.com/xml user.xsd">
    <user id="0001">
        <name>刘备</name>
        <age>25</age>
        <hobby>抽烟</hobby>
    </user>
    <user id="0002">
        <name>关羽</name>
        <age>20</age>
        <hobby>烫头</hobby>
    </user>
    <user id="0003">
        <name>张飞</name>
        <age>18</age>
        <hobby>喝酒</hobby>
    </user>
</users>
  1. 读取XML
public class testDOM4J {
    // 获取XML文件中的所有元素(标签)
    @Test
    public void test1() throws DocumentException {
        //1.获取XML解析器对象
        SAXReader reader = new SAXReader();

        //2.获取XML文档对象document
        Document document = reader.read("H:\\javase\\src\\com\\XML\\test\\user.xml");

        //3.获取根元素
        Element rootElement = document.getRootElement();

        //4.获取根元素名称
        System.out.println("根元素名称:" + rootElement.getName());

        //5.获取子节点
        List<Element> elements = rootElement.elements();

        //6.1 遍历获取全部子节点文本信息
        for (Element element : elements) {
            System.out.println("子节点名称:" + element.getName() + "的ID为:" + element.attributeValue("id"));
            List<Element> elements1 = element.elements();
            for (Element element1 : elements1) {
                System.out.println("子节点标签:" + element1.getName() + "的值为:" + element1.getText());
            }
            System.out.println("-------------------------------------");
        }

        //6.2 获取集合中第一个子节点文本信息
        Element user = elements.get(0);//获取elements第一个标签
        String id = user.attributeValue("id");//获取标签属性
        String name = user.elementText("name");//方法一:获取子标签文本
        String age = user.elementText("age");
        String hobby = user.element("hobby").getText();//方法二:获取子标签文本
        System.out.println(id + ":" + name + ":" + age + ":" + hobby);
    }
}

XPath解析器的使用(查)

  1. XPath 是一门在 XML 文档中查找信息的语言。 可以是使用xpath查找xml中的内容。 XPath 的好处
  2. 由于DOM4J在解析XML时只能一层一层解析,所以当XML文件层数过多时使用会很不方便,结合 XPATH就可以直接获取到某个元素

导入XPath

jaxen-1.1-beta-6.jar添加进myjar即可
关于导入详细信息(按照JBDC安装即可)👈点这里

XPath语法

语法说明
/AAA/DDD/BBB表示一层一层的,AAA下面 DDD下面的BBB
//BBB表示和这个名称相同,表示只要名称是BBB,都得到
//*所有元素
BBB[1] , BBB[last()]第一种表示第一个BBB元素, 第二种表示最后一个BBB元素
//BBB[@id]表示只要BBB元素上面有id属性,都得到
//BBB[@id=‘b1’]表示元素名称是BBB,在BBB上面有id属性,并且id的属性值是b1

XPath的API介绍

方法描述
selectSingleNode(query),参数是Xpath 查询串。查找和 XPath 查询匹配的一个节点。
selectNodes(query),参数是Xpath 查询串。得到的是xml根节点下的所有满足 xpath 的节点
Node节点对象

使用XPath解析XML

  1. 准备一个合格的XML(需要有约束的XML,推荐使用Schema约束)
    book.xml
    👇
<?xml version="1.0" encoding="UTF-8" ?>
<bookstore>
    <book id="book1">
        <name>金瓶梅</name>
        <author>金圣叹</author>
        <price>99</price>
    </book>
    <book id="book2">   
        <name>红楼梦</name>   
        <author>曹雪芹</author>   
        <price>69</price>
    </book>
    <book id="book3">
        <name>Java编程思想</name>
        <author>埃克尔</author>
        <price>59</price>
    </book>
</bookstore>
  1. 读取XML
	/**
     * 使用selectSingleNode() 方法 查询自定的节点信息
     */
    @Test
    public void test01() throws DocumentException {
        //1.创建xml解析对象
        SAXReader reader = new SAXReader();
        //2.获取XML文档对象document
        Document document = reader.read("H:\\javase\\src\\com\\XML\\XPath\\book.xml");

        /**
         * selectSingleNode()获取单个节点的内容
         */
        {
            System.out.println("selectSingleNode()获取单个节点的内容:");
            System.out.println("-----------------------------------------------------------");
            //通过selectSingleNode()方法获取第一本书的name节点
            Node node = document.selectSingleNode("/bookstore/book/name");
            System.out.println("节点名称:" + node.getName());
            System.out.println("书名:" + node.getText());

            System.out.println("-------------------------------------");

            //通过selectSingleNode()方法获取第二本书的name节点
            Node node1 = document.selectSingleNode("/bookstore/book[2]/name");
            System.out.println("节点名称:" + node1.getName());
            System.out.println("书名:" + node1.getText());

            System.out.println("-------------------------------------");

            //通过selectSingleNode()方法获取第三本书的name节点
            Node node2 = document.selectSingleNode("/bookstore/book[3]/name");
            System.out.println("节点名称:" + node2.getName());
            System.out.println("书名:" + node2.getText());
            System.out.println("-------------------------------------");
        }

        /**
         * selectSingleNode()获取 属性值 或者 通过属性值获取到节点信息
         */
        {
            System.out.println("selectSingleNode()获取 属性值 或者 通过属性值获取到节点信息:");
            System.out.println("-----------------------------------------------------------");
            //1.获取book.xml第一个节点中的 id属性的值
            Node node = document.selectSingleNode("/bookstore/book/attribute::id");
            System.out.println("第一个book节点的id属性是:" + node.getText());

            System.out.println("-------------------------------------");

            //2.获取book.xml最后一个节点的 id属性的值
            Node node1 = document.selectSingleNode("/bookstore/book[last()]/attribute::id");
            System.out.println("最后一个book节点的id属性是:" + node1.getText());

            System.out.println("-------------------------------------");

            //2.1.通过id的值 获取book2节点的书名
            Node node2 = document.selectSingleNode("/bookstore/book[@id = 'book2']");
            String name = node2.selectSingleNode("name").getText();
            System.out.println("id为book2的 节点书名是:" + name);

            System.out.println("-------------------------------------");
        }

        /**
         * selectNodes() 获取全部指定名称的节点
         */
        {
            System.out.println("selectNodes() 获取全部指定名称的节点:");
            System.out.println("-----------------------------------------------------------");
            //1.查询所有的节点
            List<Node> list = document.selectNodes("//*");
            for (Node node : list) {
                System.out.println("节点名:" + node.getName());
            }

            System.out.println("-------------------------------------");

            //2.获取全部书名
            List<Node> list1 = document.selectNodes("//name");
            for (Node node : list1) {
                System.out.println("书名:" + node.getText());
            }

            System.out.println("-------------------------------------");

            //3.获取 id值为book1 的节点中全部内容
            List<Node> list2 = document.selectNodes("/bookstore/book[@id = 'book1']//*");
            for (Node node : list2) {
                System.out.println(node.getName() + "=" +node.getText());
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值