一种语言...
可以用来存储数据、作配置文件用,也可以在网络上传输。现在一般就是做配置文件了。

<User>
    <name>张三</name>
</User>

语法

<?xml version="1.0" encoding="UTF-8" ?>
<!--通常来说必须要有文档说明 version是版本信息, encoding是编码
文档说明必须在第一行-->
<!--标签定义不能有空格和冒号,区分大小写-->
<!--xml中只能有一个根元素-->
<!--123是属性,只能在左半标签里。属性值必须使用单引号或者双引号包裹-->
<User id="123" number="000">
<!--    标签里夹的是文本-->
    <name>张三</name>
    <age>18</age>
<!--    自闭合(空标签)-->
    <close/>
</User>

约束

防止XML太随意而诞生的规则。

DTD语法简介

引入方法: 在文档声明下面加一行这个

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

schema

比DTD支持的约束更多,文件后缀名.xsd。太复杂了,也没人自己写,不贴了。

XML解析

通常有两种方式。一种是DOM,一种是SAX
DOM方式就是把整个DOM全读取到内存,形成一颗dom树。
优点是有结构关系,缺点是文件大会把内存***。
SAX方式可以一边扫描一边解析
优点是占用内存少,缺点是只能读,不能修改。
常见的解析器->DOM4J、jsoup

DOM4J

使用它需要jar包。图片说明

基本使用

public class TestDOM4J {
    @Test
    public void test1() throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read("E:\\java-projects\\phase-2-module-2\\src\\com\\xml\\user.xml");
        Element rootElement = document.getRootElement();
        List<Element> elements = rootElement.elements();
        for (Element e : elements) {
            System.out.println(e.getName());
            List<Element> properties = e.elements();
            for (Element ele : properties) {
                System.out.println(ele.getName());
            }
        }
    }

    @Test
    public void test2() throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read("E:\\java-projects\\phase-2-module-2\\src\\com\\xml\\user.xml");
        Element rootElement = document.getRootElement();
        List<Element> elements = rootElement.elements();
        Element element = elements.get(0);
        String id = element.attributeValue("id");
        String name = element.elementText("name");
        String age = element.elementText("age");
        String hobby = element.element("hobby").getText();
        System.out.println(id + "\t" + name + "\t" + age + "\t" + hobby);
    }
}

XPath

在XML中查找内容的语言。
由于DOM4J在解析XML时只能一层一层解析,所以当XML文件层数过多时使用会很不方便,结合XPATH就可以直接获取到某个元素
需要再导入 jaxen-1.1-beta-6.jar

例子

<?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>
public class TestXPath {
    @Test
    public void test1() throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read("E:\\java-projects\\phase-2-module-2\\src\\com\\xml\\book.xml");
        Node node1 = doc.selectSingleNode("/bookstore/book/name");
        System.out.println(node1.getName());
        System.out.println(node1.getText());
        Node node2 = doc.selectSingleNode("bookstore/book[2]/name");
        System.out.println(node2.getName());
        System.out.println(node2.getText());
    }

    @Test
    public void test2() throws DocumentException{
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read("E:\\java-projects\\phase-2-module-2\\src\\com\\xml\\book.xml");
        //此时node是属性
        Node node = doc.selectSingleNode("/bookstore/book/attribute::id");
        System.out.println(node.getText());
        Node node1 = doc.selectSingleNode("/bookstore/book[last()]/attribute::id");
        System.out.println(node1.getText());
        Node node2 = doc.selectSingleNode("/bookstore/book[@id='book2']");
        String name = node2.selectSingleNode("name").getText();
        System.out.println(name);
    }

    @Test
    public void test3() throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read("E:\\java-projects\\phase-2-module-2\\src\\com\\xml\\book.xml");
//        List<Node> list = doc.selectNodes("//*");
//        for (Node n :list)
//            System.out.println(n.getName());
//        List<Node> list1 = doc.selectNodes("//name");
//        for (Node n :list1)
//            System.out.println(n.getText());
        //查找id为book1的节点下的所有的节点
        List<Node> list = doc.selectNodes("/bookstore/book[@id='book1']//*");
        for (Node n : list) {
            System.out.println(n.getName() + "\t" + n.getText());
        }
    }
}

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">980909</property>
</jdbc>
public class JDBCUtilsPlus {
    public static String driverName;
    public static String url;
    public static String user;
    public static String password;

    static {
        try {
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read("E:\\java-projects\\phase-2-module-2\\src\\com\\xml\\user.xml");
            Node driver = document.selectSingleNode("/jdbc/property[@name='driverClass']");
            driverName = driver.getText();
            Node urlNode = document.selectSingleNode("/jdbc/property[@name='jdbcUrl']");
            url = urlNode.getText();
            Node userNode = document.selectSingleNode("/jdbc/property[@name='user']");
            user = userNode.getText();
            Node passwordNode = document.selectSingleNode("/jdbc/property[@name='password']");
            password = passwordNode.getText();
            Class.forName(driverName);
        } catch (DocumentException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        try {
            return DriverManager.getConnection(url, user, password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }

}