XML的认识和使用(xml约束、xml解析)

修改时间:2021年1月27日
作者:pp_x
邮箱:pp_x12138@163.com

XML

XML的介绍

  • XML:可扩展标记语言Extensible Markup Language
  • 特点:可扩展的,标签自定义,语法严格

XML作用

  • 存储数据:用xml存储数据移植性强
  • 配置文件:作为各种技术框架的配置文件
  • 在网络中传输:客户端可以使用XML格式向服务器端发送数据,服务器接收到xml格式数据,进行解析

XML语法

文档声明格式

  • 必须以<?xml开头,以?>结束

  • 必须写在第一行

      <?xml version="1.0" encoding="UTF-8"?>
    

versioin:指定XML文档版本。必须属性;
encoding:指定当前文档的编码。可选属性,默认值是utf-8

元素(标签)

  • 文档的重要组成部分
  • 命名规则
    • 不能使用空格,不能使用冒号
    • 区分大小写
    • 有且只有一个根元素

属性

  • 元素的一部分,必须出现在开始标签
  • 属性的定义格式:属性名=属性值,其中属性值必须使用单引或双引
  • 一个元素可以有0~N个属性,但一个元素中不能出现同名属性
  • 属性名不能使用空格、冒号等特殊字符,且必须以字母开头

注释

  • <!--开始,以-->结束

XML约束

  • xml约束可以约束一个xml文档的书写规范
  • 常见的约束有:DTDSchema
    -在这里插入图片描述

DTD约束

  • DTD(Document Type Definition),文档类型定义,用来约束XML文档。规定XML文档中元素的名称,子元素的名称及顺序,元素的属性等。
编写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 唯一的值 不能重复 值只能是字母或者下划线开头
-->
引入DTD约束
  • 写入方式
    • 内部dtd:将约束规则定义在xml文档中
    • 外部dtd:将约束的规则定义在外部的dtd文件中

语法:<!DOCTYPE 根元素 SYSTEM "约束文件路径">

Schema约束

什么是Schema约束
  • Schema是新的XML文档约束, 比DTD强大很多,是DTD 替代者
  • Schema本身也是XML文档,但Schema文档的扩展名为xsd,而不是xml。
  • Schema 功能更强大内置多种简单和复杂的数据类型
  • Schema 支持命名空间(一个XML中可以引入多个约束文档)
  • 约束示例
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://www.lagou.com/xml"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.lagou.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="200"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="numberType">
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="hehe_\d{4}"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

在这里插入图片描述

引入Schema约束
  • 查看schema文档,找到根元素,在xml中写出来
    <students> </students>
  • 根元素来自哪个命名空间。使用xmlns指令来声明
    <students xmlns="http://www.lagou.com/xml" ></students>
  • 引入 w3c的标准命名空间, 复制即可
<students
        xmlns="http://www.lagou.com/xml"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        
>
</students>
  • 引入的命名空间跟哪个xsd文件对应?
    • 使用schemaLocation来指定:两个取值:第一个为命名空间 第二个为xsd文件的路径
<students
        xmlns="http://www.lagou.com/xml"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.lagou.com/xml student.xsd"
>
</students>
  • 命名空间:指的的是一个环境,所用的标签来自哪个环境定义的

XML解析

  • 人们为不同问题提供不同的解析方式,并提交对应的解析器,方便开发人员操作XML

XML解析方式

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

XML常见的解析器

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

dom4j的使用

需要导入jar包

在这里插入图片描述

API介绍
  • 使用核心类SaxReader加载xml文档获得Document,通过Document 对象获得文档的根元素
  • SaxReader对象
    • read(…) 加载执行xml文档
  • Document对象
    • getRootElement() 获得根元素
  • Element对象
    • elements(…)获得指定名称的所有子元素。可以不指定名称
    • element(…) 获得指定名称的第一个子元素。可以不指定名称
    • getName()获得当前元素的元素名
    • attributeValue(…) 获得指定属性名的属性值
    • elementText(…)获得指定名称子元素的文本值
    • getText() 获得当前元素的文本内容
  • xml准备
<?xml version="1.0" encoding="UTF-8" ?>
<users
        xmlns="http://www.lagou.com/xml"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.lagou.com/xml user.xsd"
>
    <user id="001">
        <name>张百万</name>
        <age>25</age>
        <hobby>抽烟</hobby>
    </user>

    <user id="002">
        <name>于谦</name>
        <age>55</age>
        <hobby>烫头</hobby>
    </user>

    <user id="003">
        <name>小斌</name>
        <age>25</age>
        <hobby>喝酒</hobby>
    </user>
</users>
  • java测试
public class TestDOM4j {

    //获取XML文件中的 所有的元素名称(标签)
    @Test
    public void test1() throws DocumentException {

        //1.获取XML解析对象
        SAXReader reader = new SAXReader();

        //2.解析XML 获取 文档对象 document
        Document document = reader.read("H:\\jdbc_work\\xml_task03\\src\\com\\lagou\\xml03\\user.xml");

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

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

        //获取 根元素下的标签
        List<Element> elements = rootElement.elements();
        for (Element element : elements) {
            System.out.println("根标签下的子节点: " + element.getName());

            List<Element> eList = element.elements();
            for (Element e : eList) {
                System.out.println("user标签下的子节点" + e.getName());
            }

            break;
        }

    }

    //获取XML中标签的文本信息 和 属性信息
    @Test
    public void test2() throws DocumentException {

        //1.获取解析XML的 SAXReader
        SAXReader reader = new SAXReader();

        //2.获取文档对象
        Document document = reader.read("H:\\jdbc_work\\xml_task03\\src\\com\\lagou\\xml03\\user.xml");

        //3.获取根节点
        Element rootElement = document.getRootElement();

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

        //5.获取集合中的第一个 子节点
        Element user = elements.get(0);

        //6.获取节点中的文本信息
        String id = user.attributeValue("id");//获取属性 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方式读取XML

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

在这里插入图片描述

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
API介绍
  • selectSingleNode(query): 查找和 XPath 查询匹配的一个节点。
    • 参数是Xpath 查询串。
  • selectNodes(query): 得到的是xml根节点下的所有满足 xpath 的节点;
    • 参数是Xpath 查询串。
  • Node: 节点对象
public class TestXPath {

    /*
    *  使用selectSingleNode() 方法 查询自定的节点信息
    *
    * */
    @Test
    public void test1() throws DocumentException {

        //1.创建XML解析对象
        SAXReader reader = new SAXReader();

        //2.解析XML 获取 文档对象
        Document document = reader.read("H:\\jdbc_work\\xml_task03\\src\\com\\lagou\\xml04\\book.xml");

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

        //4.获取第二本书的书名
        Node node2 = document.selectSingleNode("/bookstore/book[3]/name");
        System.out.println("书名: " + node2.getText());
    }


    /*
    * 使用 selectSIngleNode() 方法获取 属性值 或者 通过属性值获取到节点信息
    *
    * */
    @Test
    public void test2() throws DocumentException {

        SAXReader reader = new SAXReader();

        Document document = reader.read("H:\\jdbc_work\\xml_task03\\src\\com\\lagou\\xml04\\book.xml");

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

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

        //3.通过id的值 获取book2节点 中的书名
        Node node3 = document.selectSingleNode("/bookstore/book[@id='book2']");

        String name = node3.selectSingleNode("name").getText();
        System.out.println("id为book2的 节点的书名是: " + name);

    }

    /*
    *  使用selectNodes() 获取所有指定名称 的节点
    *
    * */
    @Test
    public void test3() throws DocumentException {

        SAXReader reader = new SAXReader();

        Document document = reader.read("H:\\jdbc_work\\xml_task03\\src\\com\\lagou\\xml04\\book.xml");

        //1.查询所有的节点
        List<Node> list = document.selectNodes("//*");

        for (Node node : list) {
            System.out.println("节点名: " + node.getName());
        }

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

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

XML方式配置JDBC工具类

  • xml
<?xml version="1.0" encoding="UTF-8" ?>
<jdbc>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/db5?characterEncoding=UTF-8</property>
    <property name="user">root</property>
    <property name="password">123456</property>
</jdbc>
  • jdbcutils
public class JDBCUtils {

    //1.定义字符串变量 保存连接信息
    public static String DRIVERNAME;
    public static String URL;
    public static String USER;
    public static String PASSWORD;

    //2.静态代码块
    static{
        //使用 XPath语法 对xml中的数据进行读取
        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read("H:\\jdbc_work\\xml_task03\\src\\com\\lagou\\xml05\\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']");
            URL = url.getText();

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

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

            //注册驱动
            Class.forName(DRIVERNAME);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    //获取连接
    public static Connection getConnection(){

        try {

            Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);

            return connection;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值