XML语法

一、XML配置文件和properties配置文件的对比

在这里插入图片描述


二、XML的基本语法

<?xml version="1.0" encoding="utf-8" ?>
<!-- xml文件的文档声明,需要注意的是:必须写在文件的开头位置,必须是第一行,注释都不可以放在第一行 -->

<!-- XML文件中有且只有一个根元素users元素 -->
<users>
    <!-- 元素标签的命名中不可以包含 空格 和一些特殊符号.如 : -->
    <!--
        1.元素标签中可以设置该元素的属性和属性值,属性值使用单引号 / 双引号包裹
        2.元素的属性可以有多个
        3.元素的属性只可以写在元素的开始标签内部
    -->
    <user id="1" vip="true">
        <!-- user元素体中可以是文本内容也可以是元素标签-->
        内容
        <name>zhangfei</name>
        <age>18</age>
    </user>

    <user id="2">
        内容
        <name>guanyu</name>
        <age>20</age>
    </user>
    <!-- 元素的命名是区分大小写的 -->
    <USER>
        <NAME></NAME>
        <AGE></AGE>
    </USER>
    <!-- xml文件中也可以定义空元素标签 -->
    <close/>
</users>

三、使用XML基本语法描述数据库中表的基本信息

<?xml version="1.0" encoding="UTF-8" ?>
<users>
    <user id="1">
        <userName>林黛玉</userName>
        <password>123456</password>
    </user>

    <user id="2">
        <userName>贾宝玉</userName>
        <password>789456</password>
    </user>
</users>

在这里插入图片描述


四、XML文件的约束

在实际开发中,XML文件的书写也不是任意的,需要我们遵守一定的规则。
在这里插入图片描述

1.自定义DTD约束并引入XML文件中

(1) 定义DTD约束文件

<!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属性 叫做 number
             #REQUIRED : number的属性必须填写
             ID 表示number属性的值是 唯一的 不能重复 只能是字母或者下划线开头
        -->

(2) 引入DTD约束文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
    <student number="s1">
        <name>张飞</name>
        <age>18</age>
        <sex>1</sex>
    </student>

    <student number="s2">
        <name>黄月英</name>
        <age>18</age>
        <sex>0</sex>
    </student>
</students>

(2) 引入DTD约束文件的方式

  • 内部dtd:将约束规则定义在xml文档中
  • 外部dtd:将约束规则定义在外部的dtd文件中 。既可以引用本地的dtd文件,也可以引用网络上的dtd文件。

1.自定义schema约束并引入XML文件中

(1) 定义schema约束文件

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://www.xuguowen.com/xml"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.xuguowen.com/xml" elementFormDefault="qualified">
    <!-- 根元素是 students,类型是studentsType -->
    <xsd:element name="students" type="studentsType"/>
    <!-- 类型是studentsType 根元素的子元素是 student 最小出现次数 0 最大出现次数不限制 -->
    <xsd:complexType name="studentsType">
        <xsd:sequence>
            <xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
    <!--
        student元素的子元素是 name,age,sex。
        name标签中内容的类型是string
        age标签中内容的类型是 ageType
        sex标签中内容的类型是 sexType
    -->
    <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>
        <!-- 属性number 的类型是 numberType required表示属性是必须要有的-->
        <xsd:attribute name="number" type="numberType" use="required"/>
    </xsd:complexType>
    <!-- sex标签中内容的类型是string类型的,值可以是male、female-->
    <xsd:simpleType name="sexType">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="male"/>
            <xsd:enumeration value="female"/>
        </xsd:restriction>
    </xsd:simpleType>
    <!-- age标签中内容的类型是integet类型的,值在0 - 200 之间 -->
    <xsd:simpleType name="ageType">
        <xsd:restriction base="xsd:integer">
            <xsd:minInclusive value="0"/>
            <xsd:maxInclusive value="200"/>
        </xsd:restriction>
    </xsd:simpleType>
    <!-- 属性number的类型是string类型的,值是hehe_任意的4个数字-->
    <xsd:simpleType name="numberType">
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="hehe_\d{4}"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

(2) 引入xsd约束文件

<?xml version="1.0" encoding="UTF-8" ?><!--文档声明-->
<students
        xmlns="http://www.xuguowen.com/xml"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.xuguowen.com/xml student.xsd"
        >

    <student number="hehe_1234">
        <name>zhnagfei</name>
        <age>28</age>
        <sex>female</sex>
    </student>

    <student number="hehe_1234">
        <name>关羽</name>
        <age>200</age>
        <sex>male</sex>
    </student>

</students>

五、XML文件解析方式的介绍

1.解析概述

当将数据存储在XML后,我们就希望通过程序获得XML的内容。如果我们使用Java基础所学习的IO知识是可以完成的,不过你需要非常繁琐的操作才可以完成,且开发中会遇到不同问题(只读、读写)。
人们为不同问题提供不同的解析方式,并提交对应的解析器,方便开发人员操作XML。

2.XML解析方式

  • DOM:要求解析器把整个XML文档装载到内存,并解析成一个Document对象。

    • 优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
    • 缺点:XML文档过大,可能出现内存溢出显现。
  • SAX:是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件。(了解)

    • 优点:占用内存少 处理速度快,可以处理大文件
    • 缺点:只能读,逐行后将释放资源。

在这里插入图片描述


2.常见的XML解析器

解析器:就是根据不同的解析方式提供的具体实现。有的解析器操作过于繁琐,为了方便开发人员,有提供易于操作的解析开发包。

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

3.DOM4J API的介绍

(1)导入jar包

在这里插入图片描述

(2)常见 API介绍

  • SaxReader对象
    • read(…) 加载执行xml文档
  • Document对象
    • getRootElement() 获得根元素
  • Element对象
    • elements(…) 获得指定名称的所有子元素。可以不指定名称
    • element(…) 获得指定名称的第一个子元素。可以不指定名称
    • getName() 获得当前元素的元素名
    • attributeValue(…) 获得指定属性名的属性值
    • elementText(…) 获得指定名称子元素的文本值
    • getText() 获得当前元素的文本内容

(3)准备工作

编写user.xsd schema约束

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://www.xuguowen.com/xml"
			xmlns:xsd="http://www.w3.org/2001/XMLSchema"
			targetNamespace="http://www.xuguowen.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"/>
	</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

编写user.xml文件,引入user.xsd约束

<?xml version="1.0" encoding="UTF-8" ?>
<users
        xmlns="http://www.xuguowen.com/xml"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.xuguowen.com/xml user.xsd"
>
    <user id="001">
        <name>张飞</name>
        <age>18</age>
        <hobby>二次元</hobby>
    </user>

    <user id="002">
        <name>张百万</name>
        <age>25</age>
        <hobby>丝袜</hobby>
    </user>

    <user id="003">
        <name>波比</name>
        <age>30</age>
        <hobby>JK</hobby>
    </user>

</users>

(4)解析xml,获取xml文件中的信息

package cn.xuguowen.dom4j;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;

import java.util.List;

/**
 * @author 徐国文
 * @create 2021-09-09 9:58
 * 测试:使用dom4j的解析方式解析user.xml文件
 *  1.导入jar包
 */
public class TestDOM4j {
    /**
     * 测试获取xml文件中得根标签以及子标签
     * @throws DocumentException
     */
    @Test
    public void test1() throws DocumentException {
        // 1.创建核心对象SaxReader
        SAXReader saxReader = new SAXReader();

        // 2.调用read()方法读取指定的xml文件,获取document对象
        Document document = saxReader.read("src\\cn\\xuguowen\\dom4j\\user.xml");

        // 3.获取根标签对象
        Element rootElement = document.getRootElement();
        System.out.println("根标签的名称" + rootElement.getName());  // 根标签的名字 users

        // 4.获取根标签下的子标签user
        List<Element> elements = rootElement.elements();
        for (Element element : elements) {
            System.out.println("根标签下的子标签" + element.getName());      // user
            // 获取user标签下的子标签
            List<Element> elements1 = element.elements();
            for (Element element1 : elements1) {
                System.out.println("user标签下的子标签" + element1.getName());
            }

            break;
        }
    }

    /**
     * 获取标签中得属性和文本内容
     */
    @Test
    public void test2() throws DocumentException {
        // 1.SAXReader核心对象
        SAXReader saxReader = new SAXReader();
        // 2.读取xml文件,获取document对象
        Document document = saxReader.read("src\\cn\\xuguowen\\dom4j\\user.xml");
        // 3.获取document树中得根标签对象
        Element rootElement = document.getRootElement();
        // 4.获取根标签下得所有子标签
        List<Element> elements = rootElement.elements();
        // 5.获取了所有子标签的集合之后:list集合,可以通过索引获取其中的元素
        Element user = elements.get(0);
        System.out.println("获取到了第一个子标签是:" + user.getName());
        // 6.再去获取user标签中的子标签的内容
        String name = user.elementText("name");
        String age = user.elementText("age");
        String hobby = user.element("hobby").getText();
        // 7.获取user标签中的属性的值
        String id = user.attributeValue("id");

        System.out.println("name标签中的文本内容:" + name);
        System.out.println("age标签中的文本内容:" + age);
        System.out.println("hobby标签中的文本内容:" + hobby);
        System.out.println("id属性的值是:" + id);
    }
}


4.XPath API的介绍

XPath的优点:由于DOM4J在解析XML时只能一层一层解析,所以当XML文件层数过多时使用会很不方便,结合XPATH就可以直接获取到某个元素。

(1)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

(2)API介绍

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

(3)XPath读取XML

数据准备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>

代码实现

package cn.xuguowen.xpath;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

import java.util.List;

/**
 * @author 徐国文
 * @create 2021-09-09 20:18
 * 导入jar包
 */
public class TestXPath {
    /**
     * 使用selectSingleNode() 方法获取单个节点
     */
    @Test
    public void test1() throws DocumentException {
        // 1.核心对象SAXReader
        SAXReader saxReader = new SAXReader();
        // 2.读取xml文档,获取document对象
        Document document = saxReader.read("src\\cn\\xuguowen\\xpath\\book.xml");
        // 3.selectSingleNode()方法获取单个节点:默认情况下是获取第一个节点
        Node node1 = document.selectSingleNode("/bookstore/book/name");
        System.out.println("获取到的节点是:" + node1.getName());
        System.out.println("节点的文本内容:" + node1.getText());   // 金瓶梅

        // 获取第二个节点book中name标签中的文本内容
        Node node2 = document.selectSingleNode("/bookstore/book[2]/name");
        System.out.println("第二个book节点中name标签的文本内容:" + node2.getText());

    }

    /**
     * 通过节点获取属性值 和 通过属性值获取节点中的信息
     */
    @Test
    public void test2() throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read("src\\cn\\xuguowen\\xpath\\book.xml");

        // 通过id属性获取第一个book节点中的属性值
        Node node1 = document.selectSingleNode("/bookstore/book/attribute::id");
        System.out.println("第一个book节点的id属性值是:" + node1.getText());  // book1

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

        // 通过id属性值获取节点信息:比如:通过id属性值为book2 获取所在的节点信息
        Node node3 = document.selectSingleNode("/bookstore/book[@id='book2']");// 获取到了第二个book节点
        System.out.println(node3.selectSingleNode("name").getText());   // 红楼梦
    }

    /**
     * 测试selectNodes()方法
     */
    @Test
    public void test3() throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read("src\\cn\\xuguowen\\xpath\\book.xml");

        // 1.获取所有的节点
        List<Node> allNode = document.selectNodes("//*");
        for (Node node : allNode) {
            System.out.println("获取到的所有节点名称是:" + node.getName() + "\t");
        }

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

        // 2.获取所有的书名:书名都在name标签中
        List<Node> allName = document.selectNodes("//name");
        for (Node node : allName) {
            System.out.println(node.getText());
        }

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

        // 3.获取id属性值为book2的节点的所有信息
        List<Node> book2 = document.selectNodes("/bookstore/book[@id='book2']//*");
        for (Node node : book2) {
            System.out.println("节点名为:" + node.getName() + " 节点的内容:" + node.getText());
        }
    }
}

六、JDBC工具类自定义XML文件

1.编写jdbc-config.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<jdbc>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/day17?
        characterEncoding=UTF-8</property>
    <property name="user">root</property>
    <property name="password">root</property>

</jdbc>

2.编写JDBC工具类

package cn.xuguowen.jdbc;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * @author 徐国文
 * @create 2021-09-09 21:25
 * 使用dom4j+XPath语法解析jdbcxml文件,获取数据库的连接
 */
public class JDBCUtils {

    // 类变量保存解析xml文件获取的内容
    public static String driverName;
    public static String jdbcurl;
    public static String user;
    public static String password;

    // 静态代码块加载xml文件,读取xml文件,给类变量设置值
    static {
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read("src\\cn\\xuguowen\\jdbc\\jdbc-config.xml");
            // 1.获取驱动名称
            Node driver = document.selectSingleNode("/jdbc/property[@name='driverClass']");
            driverName = driver.getText();

            // 2.获取url
            Node url = document.selectSingleNode("/jdbc/property[@name='jdbcUrl']");
            jdbcurl = url.getText();

            // 3.获取用户名
            Node mysqlUser = document.selectSingleNode("/jdbc/property[@name='user']");
            user = mysqlUser.getText();

            // 4.获取密码
            Node pw = document.selectSingleNode("/jdbc/property[@name='password']");
            password = pw.getText();

            // 5.注册驱动
            Class.forName(driverName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库的连接
     * @return
     */
    public static Connection getConnection() {
        try {
            Connection connection = DriverManager.getConnection(jdbcurl, user, password);
            return connection;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }
}

3.测试是否可以获取连接

package cn.xuguowen.jdbc;

import org.junit.Test;

import java.sql.Connection;

/**
 * @author 徐国文
 * @create 2021-09-09 21:38
 */
public class TestConnection {
    @Test
    public void test() {
        Connection connection = JDBCUtils.getConnection();
        System.out.println(connection);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值