XML技术

  XML是一种可扩展标记语言,用来标记数据、定义数据类型,1998年由W3W发布1.0.版本,与HTML语言相比,可以自定义可扩展标签格式,但是语法严格。

  XML可以用来存储数据,可移植性强,主要充当配置文件,自定义可扩展标签格式,与properties配置文件不同(键值对对应信息),可以在网络中传递数据并解析

一、XML语法

1. 文档声明:xml文件首行必须填写xml文档说明,包括版本和编码。 <?xml version="1.0" encoding="utf-8" ?>

2. 元素

  • 开始结束标签说明不能含有空格、冒号等,可以重复成对出现,xml标签命名区分大小写
  • 只能有一个根元素,他是其他元素的父元素
  • 普通元素包含开始标签,元素体,结束标签,元素体可以是文本也可以是标签
  • 空元素只有开始标签,元素自己闭合,例<close/>
  • 文档注释<!-- 注释部分 -->包裹

3. 属性

  • 属性只能在开始标签里添加,说明当前标签的属性
  • 属性定义格式:   属性名=属性值, 属性值必须用单引号或双引号包裹
  • 一个元素可以有多个属性,但一个元素中不能出现同名的属性
  • 属性不能用空格冒号等特殊字符,必须以字母开头
<?xml version="1.0" encoding="utf-8"?>
<employees>
    <employee eid="1">
        <ename>李清照</ename>
        <age>22</age>
        <sex></sex>
        <salary>4000</salary>
        <empdate>2018-11-12</empdate>
    </employee>

    <employee eid="2">
        <ename>林黛玉</ename>
        <age>20</age>
        <sex></sex>
        <salary>5000</salary>
        <empdate>2019-03-14</empdate>
    </employee>

    <employee eid="3">
        <ename>杜甫</ename>
        <age>40</age>
        <sex></sex>
        <salary>6000</salary>
        <empdate>2019-01-01</empdate>
    </employee>
    
</employees>

二、XML约束

不同用户自定义标签不同,导致解析有不同,编写一个文档来约束一个XML文档的书写规范,保证数据的安全性和规范性,主要有DTD约束和Schema约束

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>
<!--
    !ELEMENT 元素约束
    students (student+):students 根元素,至少有一个以上student子元素
    student (name,age,sex) :student包含的子元素按顺序出现
    (#PCDATA): 普通文本内容
    ATTLIST: 用来定义属性
        student number ID #REQUIRED: student子元素中 有一个ID属性叫做 number,是必须填写的
         ID: 唯一 值只能是字母或者下划线开头
         #REQUIRED:必须填写
-->
  • 引入dtd文档到xml文档中
    • 内部dtd:将约束规则定义在xml文档中  <!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
    • 外部dtd:将约束的规则定义在外部的dtd文件中 <!DOCTYPE 根标签名 PUBLIC "dtd文件名" "dtd文件的位置URL">   
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
    <student number="S1">
        <name>李清照</name>
        <age>20</age>
        <sex></sex>
    </student>
    
    <student number="s2">
        <name>李白</name>
        <age>30</age>
        <sex></sex>
    </student>
</students>

2.schema约束

  • 是一种新的文档约束,用法和xml一样,但是文件格式以xsd结尾,功能强大,能接受多种数据类型和命名空间
  • 阅读理解
<?xml version="1.0"?>
<!-- 引用 www.w3.org/2001/XMLSchema命名空间下的数据类型前面都要加上xsd -->
<xsd:schema xmlns="http://www.lagou.com/xml"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.lagou.com/xml"
            elementFormDefault="qualified">
    <!-- 根元素是students ,类型是自定义的studentType-->
    <xsd:element name="students" type="studentsType"/>
    <xsd:complexType name="studentsType">
        <!-- studentType 包括元素名:student, 最少出现0次,可以出现很多次-->
        <xsd:sequence>
            <xsd:element name="student" type="studentType" minOccurs="0"
                         maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="studentType">
        <!-- tudentType的构成包括String  name, 定义的age格式和性别格式 -->
        <xsd:sequence>
            <xsd:element name="name" type="xsd:string"/>
            <xsd:element name="age" type="ageType" />
            <xsd:element name="sex" type="sexType" />
        </xsd:sequence>
        <!-- 元素属性 必须要有number-->
        <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">
        <!-- 年龄是0~200之间的整数-->
        <xsd:restriction base="xsd:integer">
            <xsd:minInclusive value="0"/>
            <xsd:maxInclusive value="200"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="numberType">
        <!-- number是字符串类型,必须以hehe_开头,最多出现4个数字-->
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="hehe_\d{4}"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>
  • 引入约束
    • 查看schema文档,找到根元素,在xml文档中写出来
    • 指明根元素来自哪个命名空间。使用xmlns指令来声明
    • 引入w3c的标准命名空间 "http://www.w3.org/2001/XMLSchema"
    • 使用schemaLocation来指定:第一个为命名空间 第二个为xsd文件的路径
<?xml version="1.0" encoding="utf-8">
<students xmlns="http://www.lagou.com/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schmaLocation="http://www.lagou.com/xml student.xsd">
    <student number="hehe_1234">
        <name>pc</name>
        <age>29</age>
        <sex>male</sex>
    </student>
    <student number="hehe_12">
        <name>pcmv</name>
        <age>20</age>
        <sex>male</sex>
    </student>
</students>

三、XML解析

  • XML 解析方式通常有2中,DOM和SAX;
    • DOM要求解析器把整个XML文档装载到内存,并解析成一个Document对象,以DOM树结构存储数据,可以进行增删改查CRUD,但是占用内存大,全部读取,XML内存过大可能会出现内存溢出
    • SAX以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件,逐行读取,占用内存小,只能用于读解析,读完后释放资源
  • 常见的XML解析器
    • JAXP:sun公司提供的解析器,支持DOMSAX
    • Dom4j:易用的、开源的库,用于XMLXPathXSLT,应用于Java平台,采用了Java集合框架并完全支持DOMSAXJAXP
    • jsoup:一款Java HTML解析器 ,也可以解析XML
    • PULL:Android内置的XML解析方式,类似SAX ,适用于内存小的应用
  • Dom4j的使用
    • 导入dom4j的jar包   
    • 使用核心类SaxReader 加载xml文件获取document对象,通过document对象获得根元素 常用API如下:

      • SaxReader对象通过read()加载执行xml文档
      • Document对象通过getRootElement()获取根元素
      • Element对象 中  elements()  获得指定名称的所有子元素 ;element() 获得指定名称的第一个元素  ;getName() 获得当前元素元素名 ; attrubuteValue() 获得指定属性名的属性值 ; elementText()获得指定名称子元素的文本值 ;  getText() 获得当前元素的文本内容
package Dom4j;

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

import javax.print.Doc;
import java.util.List;

public class Dom4j {
    @Test
    public void test01() throws DocumentException {
        //1. 创建SaxReader对象
        SAXReader saxReader=new SAXReader();
        //2. 解析XML获取document文档
        Document document=saxReader.read("C:\\Users\\Administrator\\Desktop\\javaJDBC\\jdbc03\\src\\Dom4j\\user.xml");
        //3.获取根元素
        Element root= document.getRootElement();
        //4. 读取根元素名称和根元素下各子标签的名称
        System.out.println(root.getName());//根元素名称
        List<Element> elements = root.elements();
        for (Element element : elements) {
            System.out.println("根标签下的节点名称"+element.getName());//子标签名称
            List<Element> list = element.elements();
            for (Element element1 : list) {
                System.out.println("子标签下的节点名称"+element1.getName()); //子标签下的元素
            }
        }
    }
@Test
    public void test02() throws DocumentException {
        //1.创建SaxReader对象
        SAXReader saxReader=new SAXReader();
        //2.解析xml文件获取document
        Document document= saxReader.read("C:\\Users\\Administrator\\Desktop\\javaJDBC\\jdbc03\\src\\Dom4j\\user.xml");
        //3.获取根节点
        Element root = document.getRootElement();
        //4. 获取具体节点的内容
        List<Element> elements = root.elements();
          //按索引获取第一个索引下的标签
        Element user = elements.get(0);
            //获取具体信息
        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="+id+" "+"name"+name+" "+"age"+age+" "+"hobby"+hobby);
    }
}
  •  XPath的使用:dom4j只能一层一层解析XML文件,按结构树解析,用XPath可以直接获取XML中的元素信息
    • 导入jar包
    • dom4j支持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)查找单个节点;selectNodes(query)查找XML根节点下的满足条件的所有节点;Node是节点对象

    

package 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;

public class XpathTest {

    @Test
    public void test01() throws DocumentException {

        //1. 创建SaxReader
        SAXReader saxReader= new SAXReader();
        //2. 创建document对象
        Document document= saxReader.read("C:\\Users\\Administrator\\Desktop\\javaJDBC\\jdbc03\\src\\XPath\\book.xml");
        //3. 获取根节点下的子节点的name节点
        Node node = document.selectSingleNode("/bookstore/book/name");
        System.out.println("节点名为"+node.getName());
        System.out.println("书名"+node.getText());
        //4. 获取第二本书
        Node node1 = document.selectSingleNode("/bookstore/book[2]/name");
        System.out.println("节点名为"+node1.getName());
        System.out.println("书名"+node1.getText());
        //5. 获取最后一本书
        Node node2 = document.selectSingleNode("/bookstore/book[last()]/name");
        System.out.println("节点名为"+node2.getName());
        System.out.println("书名"+node2.getText());
        //6.获取第一个book节点的 id属性的值
        Node node3 = document.selectSingleNode("/bookstore/book/attribute::id");
        System.out.println("属性名为"+node3.getName());
        System.out.println("属性值"+node3.getText());
        //7.获取最后一个book节点的 id属性的值
        Node node4 = document.selectSingleNode("/bookstore/book[last()]/attribute::id");
        System.out.println("属性名为"+node4.getName());
        System.out.println("属性值"+node4.getText());
        //8.获取id属性值为 book2的 书名
        Node node5 = document.selectSingleNode("/bookstore/book[@id='book2']");
        System.out.println("书名为"+node5.selectSingleNode("name").getText());

    }

    @Test
    public void test02() throws DocumentException {

        //1. 创建SaxReader
        SAXReader saxReader=new SAXReader();
        //2. 创建document对象
        Document document=saxReader.read("C:\\Users\\Administrator\\Desktop\\javaJDBC\\jdbc03\\src\\XPath\\book.xml");
        //3. 获取所有节点
        List<Node> list = document.selectNodes("//*");
        for (Node node : list) {
            System.out.println(node.getName());
        }
        //4. 获取所有书名
        List<Node> list1 = document.selectNodes("//name");
        for (Node node : list1) {
            System.out.println("书名:"+node.getText());
        }
        //5.获取id属性值为 book2的 所有节点信息
        List<Node> list2 = document.selectNodes("/bookstore/book[@id='book2']//*");
        for (Node node : list2) {
            System.out.println(node.getName()+"="+node.getText());
        }

    }
}

四、JDBC自定义XML

1.自定义jdbc-config.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<jdbc-config>
    <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>
    <property name="initialPoolSize">10</property>
    <property name="maxIdleTime">30</property>
    <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property>
</jdbc-config>

2. 先写jdbcutils工具类

package JDBCUtils;

import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.sql.*;

public class JDBCUtils {
    //1. 定义成员变量
    public static String DRIVERNAME;
    public static String URL;
    public static String USER;
    public static String PASSWORD;
    //2.静态代码块解析xml文件并
    static {
        // 创建SaxReader对象
        SAXReader reader = new SAXReader();
        //获取DOCUMENT 对象
        try {
            Document document = reader.read("C:\\Users\\Administrator\\Desktop\\javaJDBC\\jdbc03\\src\\JDBCUtils\\jdbc-config.xml");
            //解析需要获取的指定名称
            Node node = document.selectSingleNode("/jdbc-config/property[@name='driverClass']");
            DRIVERNAME=node.getText();
            Node node1 = document.selectSingleNode("/jdbc-config/property[@name='jdbcUrl']");
            URL=node1.getText();
            Node node2 = document.selectSingleNode("/jdbc-config/property[@name='user']");
            USER=node2.getText();
            Node node3 = document.selectSingleNode("/jdbc-config/property[@name='password']");
            PASSWORD=node3.getText();
           //注册驱动
            Class.forName(DRIVERNAME);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //3. 提供连接方法
    public  static Connection getConnection(){
        try {
            Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
            return connection;
        } catch (SQLException e) {
            e.printStackTrace();
            return  null;
        }
    }

    //4.关闭流
    public static void close(Connection con, Statement statement){
        if (con!=null && statement!=null){
            try {
                statement.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void close(Connection con, Statement statement, ResultSet resultSet){
        if (resultSet!=null){
            try {
                resultSet.close();
                JDBCUtils.close(con,statement);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

3. 进行测试

package JDBCUtils;

import java.sql.*;

public class JDBCtest {
    public static void main(String[] args) {
        //1.获取连接
        Connection connection = JDBCUtils.getConnection();
        //2. 执行SQL语句
        PreparedStatement ps  = null;
        ResultSet resultSet=null;
        try {
            ps = connection.prepareStatement("select * from employee");
            //3. 处理结果集
            resultSet = ps.executeQuery();
            while(resultSet.next()){
                int id = resultSet.getInt("eid");
                String ename = resultSet.getString("ename");
                int age = resultSet.getInt("age");
                String sex = resultSet.getString("sex");
                double salary = resultSet.getDouble("salary");
                Date empdate = resultSet.getDate("empdate");
                System.out.println(id+" : "+ename+" : "+age+" : "+sex+" : "+salary+" : "+empdate);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //4. 关闭连接
            JDBCUtils.close(connection,ps,resultSet);
        }


    }
}

 

posted @ 2020-12-23 19:05  forever_fate  阅读(393)  评论(0)    收藏  举报