JavaWeb——(6)xml

目录

一、XML简介

二、XML基本语法

三、XML创建

四、XML约束

4.1 dtd约束

4.2 schema约束

五、xml解析

5.1xml解析作用

5.2xml解析思想

六、xml常用解析器

6.1JAXP

6.2JDOM

6.3DOM4J

七、XPATH


 

一、XML简介

XML全称为eXtensible Markup Language,是一种可扩展标记语言,

在XML中,所有的标签都是自定义的,常常用于存储数据,比如配置文件或者数据传输,

XML和之前学习的HTML都是标记语言,主要有以下几点区别:

  • html语法松散,xml语法严格
  • html用作页面展示,xml用作数据存储
  • html所有标签都是预定义的,xml所有标签都是自定义的

 

二、XML基本语法

关于XML的基本语法,W3C(World Wide Web Consortium,万维网联盟)公布了XML1.0标准

  • 文档声明
    • 必须写在xml文档的第一行,写法为:<?xml version="1.0" ?>
    • 属性
      • version:版本号,固定值为1.0
      • encoding:指定文档的码表,默认值为iso-8859-1
      • standalone:指定文档是否独立,yes或no
  • 元素
    • 即xml文档中的标签,文档中必须有且只能有一个根元素
    • 元素需要正确的闭合
    • 元素需要正确的嵌套
    • 元素名称要遵守
      • 元素名称区分大小写
      • 数字不能开头
  • 文本
    • 转义字符:例如&gt;为">",&lt;为“<”等
    • CDATA:里面的数据会原样显示,<![CDATA[ 数据内容 ]]>
  • 属性
    • 属性值必须用引号括起来,单引号双引号都可以
  • 注释
    • <!--注释内容-->
  • 处理指令
    • <?xml-stylesheet type="text/css" href="1.css"?>,现在基本不使用

 

三、XML创建

根据XML的语法我们创建一个XML文件book.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<books>
    <book>
        <name>java</name>
        <price>15</price>
    </book>
    <book>
        <name>C++</name>
        <price>20</price>
    </book>
    <book>
        <name>python</name>
        <price>15</price>
    </book>
</books>

 

四、XML约束

约束就是xml的书写规则,我们一般分为dtd和schema两种。

 

4.1 dtd约束

dtd按照定义的方式又可以分为内部dtd和外部dtd:

  • 内部dtd:在xml内部定义dtd
  • 外部dtd:在外部文件中定义dtd
    • 本地dtd文件:<!DOCTYPE students SYSTEM "student.dtd">
    • 网络dtd文件:<!DOCTYPE students PUBLIC "名称空间" "student.dtd">

首先我们先定义好一个dtd文件

<!ELEMENT books (book*)> <!--定义根标签为books,根标签内部的标签为book,及book出现的次数为0次或多次-->
<!ELEMENT book (name,price)> <!--定义book标签内部标签为name标签或者price标签-->
<!ELEMENT name (#PCDATA)> <!--定义name标签内部为字符串-->
<!ELEMENT price (#PCDATA)> <!--定义price标签内部为字符串-->
<!ATTLIST book id ID #REQUIRED> <!--定义book标签体有必须的属性为id-->

然后通过本地dtd文件外部引入的方式,引入到book.xml中,

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE books SYSTEM "../book.dtd"> <!--添加同路径下的dtd约束文件-->
<books>
    <book id="b100">
        <name>java</name>
        <price>15</price>
    </book>
    <book id="b101">
        <name>C++</name>
        <price>20</price>
    </book>
    <book id="b102">
        <name>python</name>
        <price>15</price>
    </book>
</books>

这时xml文件就受到dtd文件的约束了,如果去掉id属性就会报错,或者添加别的没在dtd文件中定义的标签也会报错。

我们还可以直接将约束条件写在xml文件中,利用内部引入的方式对xml文件进行约束,

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE
        <!ELEMENT books (book*)> <!--定义根标签为books,根标签内部的标签为book,及book出现的次数为0次或多次-->
        <!ELEMENT book (name,price)> <!--定义book标签内部标签为name标签或者price标签-->
        <!ELEMENT name (#PCDATA)> <!--定义name标签内部为字符串-->
        <!ELEMENT price (#PCDATA)> <!--定义price标签内部为字符串-->
        <!ATTLIST book id ID #REQUIRED> <!--定义book标签体有必须的属性为id-->
        > 
<books>
    <book id="b100">
        <name>java</name>
        <price>15</price>
    </book>
    <book id="b101">
        <name>C++</name>
        <price>20</price>
    </book>
    <book id="b102">
        <name>python</name>
        <price>15</price>
    </book>
</books>

 

4.2 schema约束

上述dtd约束有一个很大的问题,只能约束数据类型,但是对数据检查不严谨,

比如我们可以设置price的内容为abc,显然这个数据是没有实际意义的,所以就要用到schema约束,

而且schema相对于dtd有一个明显的好处就是,schema是基于XML编写的,自己本身也是一个XML文档(文件后缀名为.xsd),而不是像dtd有自成一套的语法,这也是schema能比dtd更被广泛应用的原因。

我们先创建一个xsd文件,建立好schema约束

<?xml version="1.0"?>
<xsd:schema xmlns="http://www.itcast.cn/xml"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.itcast.cn/xml" elementFormDefault="qualified">
    <xsd:element name="books" type="booksType"/>
    <xsd:complexType name="booksType">
        <xsd:sequence>
            <xsd:element name="book" type="bookType" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="bookType">
        <xsd:sequence>
            <xsd:element name="name" type="xsd:string"/>
            <xsd:element name="price" type="priceType"/>
        </xsd:sequence>
        <xsd:attribute name="id" type="idType" use="required"/>
    </xsd:complexType>
    <xsd:simpleType name="priceType">
        <xsd:restriction base="xsd:double">
            <xsd:minInclusive value="0"/>
            <xsd:maxInclusive value="10000"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="idType">
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="bookID_\d{4}"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

然后导入xsd文件,引入实例名称空间,修改对应的xml文件,使其满足schema约束

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

<books
        xmlns="http://www.itcast.cn/xml"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.itcast.cn/xml book.xsd"
>
    <book id="bookID_1000">
        <name>java</name>
        <price>30</price>
    </book>
    <book id="bookID_1001">
        <name>C++</name>
        <price>20</price>
    </book>
    <book id="bookID_1002">
        <name>python</name>
        <price>15</price>
    </book>
</books>

 

五、xml解析

5.1xml解析作用

xml解析就是对xml文件进行分析,得到其中记录的数据信息,

  • 如果将xml作为配置文件,可以通过读取配置信息
  • 如果讲xml作为传输文件,可以通过读写传输数据

 

5.2xml解析思想

xml按照解析的思想分为DOM和SAX两种,

  • DOM:将文档加载进内存,形成一颗DOM树(Document对象),将文档的各个组成部分封装为一些对象
    • 优点:在内存中形成DOM树,可以进行增删改查
    • 缺点:DOM树非常占用内存,解析速度比较慢
    • Document、Element、Text、Attribute、Comment
  • SAX:逐行读取文档,解析到某一个对象就将对象名称返回,基于事件驱动
    • 优点:不占用内存,速度较快
    • 缺点:只能读取,不能回写,无法实现增删改操作

 

六、xml常用解析器

DOM、SAX都是一组解析XML文档的规范,其实就是接口,这说明需要有实现者能使用,

而解析器就是对DOM、SAX的实现了,一般解析器都会实现DOM、SAX两个规范。

 

6.1JAXP

JAXP是由Java提供的,用于隐藏底层解析器的实现。

支持DOM和SAX两种解析,

 

6.2JDOM

JDOM是一种使用xml的独特java工具包,作用是新建xml文档以及读写xml数据。

 

6.3DOM4J

DOM4J是JDOM的升级版本,是这三种常用解析器中性能最好的一种,也是使用最多的一种。

DOM4J意为dom for java,支持DOM解析,其解析的步骤一般为:

  1. 导入jar包——dom4j.jar
  2. 创建解析器:SAXReader reader=new SAXReader();
  3. 解析xml获得document对象:Document document=reader.read(url);

下面我们读取一个xml文档的标签,

import java.util.List;

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


public class xmlParsing {
    public static void main(String[] args) throws DocumentException {
        SAXReader saxReader=new SAXReader();//创建一个xml解析器
        Document document=saxReader.read("src/book.xml");//把xml文档加载到document对象中

        Element root=document.getRootElement();//获取DOM树的根节点
        List list=root.elements();//获取根节点下的所有元素
        treeWalk(root);//遍历DOM树所有节点
    }

    public static void treeWalk(Element element){
        System.out.println(element.getName());//输出当前节点名字
        int size=element.nodeCount();//获得当前节点孩子节点的数目
        for (int i = 0; i < size; i++) {
            Node node=element.node(i);//获得当前节点
            if(node instanceof Element){//如果该节点存在
                treeWalk((Element)node);//递归调用遍历节点函数
            }
        }
    }
}

运行结果:

JavaWeb——(6)xml

这里需要导入dom4j的jar包,需要的可以自取

链接:https://pan.baidu.com/s/1pw3n2Uz8ZaGgjWkmh-3xug 
提取码:13vd 

 

七、XPATH

XPATH是专门用于查询xml信息的语言,

常用到的查询方法为,

selectSingleNode();//查找单个节点
selectNodes();//查找多个节点

XPath语法类似于文件系统中的定位文件,具体语法如下:

  • 如果路径以斜线 / 开始, 那么该路径就表示到一个元素的绝对路径。
    • /AAA,查询根节点AAA
    • /AAA/CCC,查询根节点AAA的所有CCC子元素
  • 如果路径以双斜线 // 开头, 则表示选择文档中所有满足双斜线//之后规则的元素(无论层级关系)。
    • //BBB,查询标签为BBB的所有节点,无论是否为根节点
    • //DDD/BBB,查询所有父元素为DDD的BBB元素
  • 星号 * 表示选择所有由星号之前的路径所定位的元素。
    • //*,查询所有层级的所有元素
    • /*/*/*/BBB,查询有三个祖先节点的BBB元素
  • 方块号里的表达式可以进一步的指定元素, 其中数字表示元素在选择集里的位置, 而last()函数则表示选择集中的最后一个元素。
    • /AAA/BBB[1],查询根节点AAA中的第一个BBB子元素
    • /AAA/BBB[last()],查询根节点AAA中最后一个BBB子元素
  • @表示选择指定属性的元素
    • //@id,查询所有的id属性
    • //BBB[@id],查询有id属性的BBB元素
  • 属性的值可以被用来作为选择的准则
    • //BBB[@id='b1'],查询含有属性id且其值为'b1'的BBB元素
  • count()函数可以计数所选元素的个数
    • //*[count(BBB)=2],选择含有2个BBB子元素的元素
  • 多个路径可以用分隔符 | 合并在一起
    • //CCC | //BBB,选择所有的CCC和BBB元素
  • ..表示当前节点的父节点

我们利用selectSingleNode方法查询book.xml中第三本书的价格,

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

public class xmlXPath {
    public static void main(String[] args) throws DocumentException {
        SAXReader saxReader=new SAXReader();//创建一个xml解析器
        Document document=saxReader.read("src/book.xml");//把xml文档加载到document对象中
        Node node=document.selectSingleNode("/books/book[3]/price");//获取books标签下3号book标签的price标签节点
        System.out.println(node.getText());//获取该书本的价格
    }
}

查询结果:

JavaWeb——(6)xml

我们还需要额外导入jaxen的jar包,需要的自取

链接:https://pan.baidu.com/s/1hQhX0QNvOY6rSVoUhNVdqg 
提取码:whqo 

 

我们再练习一下selectNodes方法获得所有节点进行遍历,

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

import java.util.List;

public class xmlXPath {
    public static void main(String[] args) throws DocumentException {
        SAXReader saxReader=new SAXReader();//创建一个xml解析器
        Document document=saxReader.read("src/book.xml");//把xml文档加载到document对象中

        List list=document.selectNodes("//*");//取出xml文件中的所有层级的标签节点
        for (int i = 0; i < list.size(); i++) {
            Node node=(Node)list.get(i);//依次获取节点
            if("".equals(node.getText().trim()));else {
                System.out.println(node.getText());
            }
        }
    }
}

查询结果:

JavaWeb——(6)xml

 

上一篇:Delphi 正则表达式之TPerlRegEx 类的属性与方法(7): Split 函数


下一篇:JSP-显示九九乘法表