XML的学习

380 阅读4分钟

一、XML概述

  • 什么是XML

  • XML 指可扩展标记语言(EXtensible Markup Language)
  • XML 是一种标记语言,很类似 HTML
  • XML 的设计宗旨是传输数据,而非显示数据
  • XML 标签没有被预定义。您需要自行定义标签。
  • XML 被设计为具有自我描述性。
  • XML和HTML的区别

XML 被设计为传输和存储数据,其焦点是数据的内容。

HTML 被设计用来显示数据,其焦点是数据的外观。

HTML 旨在显示信息,而 XML 旨在传输信息。

  • XML语法规则

  • XML文档声明

对于xml文档,必须要写文档声明,文档声明固定写法,只能出现正在0行0列位置

<?xml version="1.0" encoding="utf-8" ?>
  • XML文档组成:

标签:Element 标签元素
标签的属性: attribute
标签的属性值:attributeValue
标签体文本:text
  • XML语法规则

- 严格区分大小写
- 属性值必须有引号
- 文档必须有根元素
- 所有 XML 元素都须有关闭标签
  • 二、 配置文件

XML和properties文件都是配置文件,配置文件是用于给应用程序提供配置参数以及初始化设置的一些有特殊格式的文件

  • properties文件配置(实例druid.properties)

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bookstore?rewriteBatchedStatements=true
username=root
password=888888
  • XML文件配置

<?xml version="1.0" encoding="UTF-8" ?>
        <!--xml编写数据库配置-->
<config>
<!--配置数据库驱动-->
<jdbc name="driver" value="com.mysql.jdbc.driver"/>
<jdbc name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf8"/>
<jdbc name="user" value="root"/>
<jdbc name="password" value="root"/>
</config>

通过对比,可以看出XML必须在0行0列位置位置写文档声明,标签,属性名字可以自定义。

  • 三、 XML的约束

  • DTD

DTD(Document Type Definition),文档类型定义,用来约束XML文档。规定XML文档中元素的名称,子元素的名称及顺序,元素的属性等。(如何建立XML文档:新建file写文件名时加后缀.xml)。 dtd文件

<?xml version="1.0" encoding="UTF-8"?>
        <!ELEMENT beans (bean*,import*) >
        <!--*表示0次或多次,逗号(,)表示顺序-->
        <!ELEMENT bean (property*)>
        <!ELEMENT property (#PCDATA)>

        <!ELEMENT import (#PCDATA)>
        
         <!--bean里面 必须有id,className-->
        <!ATTLIST bean id CDATA #REQUIRED
                className CDATA #REQUIRED
                >
                
        <!--property里面 必须有name,value-->
        <!ATTLIST property name CDATA #REQUIRED
                value CDATA #REQUIRED
                >
                
        <!--import里面必须有resource-->
        <!ATTLIST import resource CDATA #REQUIRED>

如果开发人员需要在xml使用当前DTD约束,必须包括DOCTYPE。格式如下: DOCTYPE beans SYSTEM "bean.dtd">

<?xml version="1.0" encoding="UTF-8" ?>
<!--根据已经存在的 dtd约束,编写自己的xml配置-->
<!--引入一个外部的dtd文件,作用是控制我们自己的xml编写-->
<!DOCTYPE beans SYSTEM "beans.dtd">

<beans>

   <bean id="a" className="className">
       <property name="zhangsan" value="123">
           随意写文本
       </property>
   </bean>

   <import resource="resource">
   </import>

</beans>
  • Schema

文档扩展名为xsd,Schema模拟spring规范,如果开发人员需要在xml使用当前Schema约束,必须包括指定命名空间(namespace,简称xmlns,等同于java中的导入包)。格式如下:

beans xmlns="www.atguigu.com/bean" xmlns:xsi="www.w3.org/2001/XMLSch…" xsi:schemaLocation="www.atguigu.cn/bean bean-schema.xsd"

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.atguigu.cn/bean"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:tns="http://www.atguigu.cn/bean"
        elementFormDefault="qualified">
    <!-- 声明根标签 -->
    <element name="beans">
        <complexType>
            <choice minOccurs="0" maxOccurs="unbounded">
                <element name="bean">
                    <complexType>
                        <sequence minOccurs="0" maxOccurs="unbounded">
                            <element name="property">
                                <complexType>
                                    <attribute name="name" use="required"></attribute>
                                    <attribute name="value" use="required"></attribute>
                                </complexType>
                            </element>
                        </sequence>
                        <attribute name="id" use="required"></attribute>
                        <attribute name="className" use="required"></attribute>
                    </complexType>
                </element>
                <element name="import">
                    <complexType>
                        <attribute name="resource" use="required"></attribute>
                    </complexType>
                </element>
            </choice>
        </complexType>
    </element>
</schema>

使用已有的 sxd文件,编写我们自己的xml

<?xml version="1.0" encoding="UTF-8" ?>
<qq:beans xmlns:qq="http://www.atguigu.cn/bean"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.atguigu.cn/bean beans.xsd"
>
   
    <qq:bean id="a"
             className="sss">
        <qq:property name="sss" value="www"/>

    </qq:bean>

<qq:import resource="sss"/>
    
    <qq:import resource="ddd"/>

 </qq:beans>
  •   xmlns="http://www.atguigu.cn/bean" xml命名空间的名字
    W3C的标准:命名空间的名字,必须是全球唯一性
    
  •    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      W3C的官方约束
    
  •    xsi:schemaLocation="http://www.atguigu.cn/bean beans.xsd"
     定义的是,约束的命名空间,和约束的文件路径
    

四、XML的解析(重点)

  • XML解析的作用

用Java代码读取xml中的数据

  • 解析方式

  • dom解析:将文档加载进内存,形成一颗dom树(document对象),将文档的各个组成部分封装为一些对象。dom树非常占内存,解析速度慢。所以一般解析体积较大的XML文件的时候不会采用DOM解析
  • SAX解析:逐行读取,基于事件驱动,解析一行释放一行,内存占用非常小。解析体积较大的XML文件的时候不会采用
  • 解析器

  1. JAXP: sun公司提供的解析。支持dom和sax。(不常用)
  2. JDOM
  3. DOM4J(常用)

DOM4J使用

  1. 在src下创建xml文件,student.xml
<?xml version="1.0" encoding="UTF-8" ?>
<students>
    <student name="张三" age="20">
        <score name="数学">100</score>
        <score name="语文">30</score>
    </student>

    <student name="李四" age="21">
        <score name="数学">15</score>
        <score name="语文">99</score>
    </student>
</students>
  1. 在模块下建立lib包,导包dom4j.jar(核心类是SaxReader)
  2. 创建ReadXml类读取xml
package com.atguigu.read;

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

import java.io.InputStream;
import java.util.List;

public class ReadXml {
    public static void main(String[] args) throws Exception {
        //字节输入流,绑定xml文件
        InputStream input
        =ReadXml.class.getClassLoader().getResourceAsStream("student.xml");
        //创建核心类对象
        SAXReader saxReader = new SAXReader();
        //saxReader方法read,传递输入流,读取xml文件,返回文档对象 Document
        Document document = saxReader.read(input);
       
        //读取文档的根标签:students
        Element rootElement = document.getRootElement();
        
        //读取根标签的子标签 student,
        // 根标签对象rootElement的方法,List<Element> elements() 返回List集合
        List<Element> studentElements = rootElement.elements();
        for(Element studentElement : studentElements){
            //studentElement对象,每一个student标签对象
            //studentElement对象方法 attributeValue(属性名) 获取属性值,返回字符串
            String name = studentElement.attributeValue("name");
            String age = studentElement.attributeValue("age");
            System.out.println(name+"::"+age);
            //获取student标签的子标签 score 多个标签
            List<Element> scoreElements = studentElement.elements();
            for(Element scoreElement : scoreElements){
                //scoreElement 获取的是子标签score
                //score标签的属性值
                String scoreName =  scoreElement.attributeValue("name");
                //score标签体获取,是普通文本字符串 scoreElement方法getText()
                String text = scoreElement.getText();
                System.out.println("\t"+scoreName+"::"+text);
            }
        }
    }
}
  • 获取所有子标签 List<Element> sonElementList = rootElement.elements();
  • 获取指定标签名的子标签 List<Element> sonElementList = rootElement.elements("标签名");
  • 获取某个标签属性的值 String value = element.AttributeValue("属性名");

XPATH使用

使用XPATH工具,直接定位,速度快,代码量少,导jaxen-1.1-beta-6.jar包

package com.atguigu.read;

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

import java.io.InputStream;
import java.util.List;

public class XpathXml {
    public static void main(String[] args) throws Exception{
        //字节输入流,绑定xml文件
        InputStream input =
                ReadXml.class.getClassLoader().getResourceAsStream("student.xml");
        //创建核心对象
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(input);
        Element rootElement = document.getRootElement();
        //直接读取,定位标签 score
        //标签对象的方法 List<> selectNodes("//标签名"),返回值集合List
        List scoreElements = rootElement.selectNodes("//score");
        for(Object object : scoreElements){
            //Object强制转成标签对象
            Element scoreElement = (Element)object;
            System.out.println(scoreElement.attributeValue("name")+"::"+ scoreElement.getText());
        }
        System.out.println("==============");

        //selectSingleNode方法,获取一个标签,返回值Node接口对象
        //标签对象Element接口,继承Node接口
        Element node = (Element) rootElement.selectSingleNode("//score");
        System.out.println(node.attributeValue("name")+"::"+node.getText());
    }
}

selectSingleNode("路径规则"): 根据路径规则,查找满足条件的第一个节点 selectNodes("路径规则"): 根据路径规则,查找满足条件的所有节点