JavaSE@拓展补遗@笔记18@XML介绍&&XML的两种约束&&XML的DOM4j解析

一、.XML

1、XML介绍

XML 指可扩展标记语言(Extensible Markup Language)

XML中没有预定义标签,所有的标签都是自己定义的。

XML是W3C组织的一个语言。

W3C在1988年2月发布XML1.0版本,我们现在用的就是1.0版本。在后面也有新的版本,但是新版本不太兼容旧版本,所以新版本没有被推广开。

2、编写XML

<天气预报>
    <北京>
        <东城区>
            <最高温度>12℃</最高温度>
            <最低温度>-2℃</最低温度>
        </东城区>
        <西城区>
            <最高温度>13℃</最高温度>
            <最低温度>-1℃</最低温度>
        </西城区>
        <顺义区>
            <最高温度>14℃</最高温度>
            <最低温度>-3℃</最低温度>
        </顺义区>
    </北京>
    <天津>
        <武清区>
            <最高温度>15℃</最高温度>
            <最低温度>2℃</最低温度>
        </武清区>
        <南开区>
            <最高温度>20℃</最高温度>
            <最低温度>6℃</最低温度>
        </南开区>
    </天津>
</天气预报>

3、XML的作用

  1. 可以传输数据,作为数据传输的载体
  2. 可以作为配置文件,保存配置信息

(properties用来存储一对一的键值对信息,xml用来存储有上下级关系的信息)

4、XML的组成部分

文档声明

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

注意事项:

  1. 文档声明必须以<?xml开头 , 必须以?>结尾
  2. 文档声明必须写在第一行第一列
  3. version表示版本,encoding表示编码
  4. 文档声明可以不写

元素

  1. 元素是XML中最重要的组成部分,元素也叫标签
  2. 标签分为开始标签和结束标签,开始标签<名字> 结束标签</名字>
  3. 开始标签和结束标签中间写的是标签内容,标签的内容可以是文本,也可以是其他标签
  4. 如果标签没有任何内容,那么可以定义为 自闭合标签(<名字/>)
  5. 命名规则: ​ 不要使用XML xML xml 写样的单词,不能使用空格,冒号等特殊字符,命名区分大小写
  6. 一个XML文件有且仅有一个根标签

属性

  1. 属性是标签的一部分,属性必须写在开始标签或自闭合标签中,不能写在结束标签中
  2. 属性的书写格式:属性名=属性值,属性值必须使用单引号或双引号括起来,在XML中,单引和双引是没区别的。
  3. 一个元素可以有任意个属性,但是属性之间不能重名,多个属性之间用空格隔开
  4. 属性名不能使用特殊字符,必须以字母开头

注释

对代码的解释说明

<!-- 注释  -->
快捷键: ctrl+/   (是idea的注释快捷键,idea会自动识别语言匹配对应的注释)

转义字符

有些特殊的字符在XML中是会被识别的,比如<在XML中会被识别为标签,如果想要写这样的符号,需要用转义字符.

<      &lt;
>      &gt;
"      &quot;

<abc> 3 &lt; 4   </abc>

CDATA区 (了解)

如果有大量的转义字符,可能就降低代码的阅读性,所以可以使用CDATA区去代替转义字符,在CDATA区中的文本不会被识别为特殊符号。

<!--CDATA区-->
<abc>   <![CDATA[  <<<<<<<>>>>>>>>   ]]>      </abc>

二、XML文档的约束

1、概念

因为XML语言没有任何预定义标签,写任何标签都是可以的,这样导致解析比较困难复杂。

约束是对XML文件进行限制的,约束可以规定XML的标签内容和嵌套方式。

约束文件一定不会让我们自己写,但是今天理解一下约束的内容。

2、DTD约束

介绍

DTD约束写法简单,但是对XML的约束不是很严格,无法约束具体的数据类型。

DTD约束的文件后缀名.dtd

DTD约束文档

<!--
    复制内容如下到XML文件中:
        <!DOCTYPE 书架 SYSTEM "bookdtd.dtd">
​
-->
        <!--Element表示元素,元素名称是书架,书架里书作为子元素-->
        <!ELEMENT 书架 (书+)>
        <!--书也是一个元素,书的子元素是书名,作者,售价-->
        <!ELEMENT 书 (书名,作者,售价)>
        <!--书名也是一个元素,#PCDATA表示书名里面是文本-->
        <!ELEMENT 书名 (#PCDATA)>
        <!--作者也是一个元素,#PCDATA表示作者里面是文本-->
        <!ELEMENT 作者 (#PCDATA)>
        <!--售价也是一个元素,#PCDATA表示售价里面是文本-->
        <!ELEMENT 售价 (#PCDATA)>

DTD引入方式

1.内部DTD,在XML文档内部嵌入DTD,只对当前XML有效
    <!DOCTYPE 根元素 [...//具体语法]>
    
2.外部DTD—本地DTD
    <!DOCTYPE 根元素 SYSTEM "约束文件名称">
    
3.外部DTD—公共DTD
    <!DOCTYPE 根标签 PUBLIC "dtd的名字" "网络上的位置">

xml需要使用DTD就要先引入dtd,但是这个代码一定不用我们写,一定是会提供的。

按照上面的dtd约束编写XML

<!DOCTYPE 书架 SYSTEM "bookdtd.dtd">
<书架>
    <书>
        <书名>java从入门到放弃</书名>
        <作者>高斯林</作者>
        <售价>99.8</售价>
    </书>
</书架>

DTD约束的符号介绍

?   :表示一个或零个
*   :表示任意个
+   :表示一个或多个
​
,   :表示按照顺序依次出现
|   :表示或者

3、Schema约束

介绍

Schema约束能够对xml做出更严格的限制,可以对数据类型做精确的要求。

Schema约束的后缀名是.xsd

Schema约束文档

<?xml version="1.0" encoding="UTF-8" ?>
<!--    传智播客教学实例文档.将注释中的以下内容复制到要编写的xml的声明下面
​
​
复制内容如下到XML文件中:
​
<书架 xmlns="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn bookSchema.xsd" >
​
</书架>
​
​
-->
<xs:schema
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.itcast.cn"
        elementFormDefault="qualified">
    <!--element表示元素 元素名是书架-->
    <xs:element name='书架'>
        <!--complextype表示书架是一个复杂标签(里面有子标签)-->
        <xs:complexType>
            <!--sequence表示顺序出现   maxOccurs表示最大出现次数-->
            <xs:sequence maxOccurs="3" >
                <!--书架的子标签是书-->
                <xs:element name='书'>
                    <!--表示书也是一个复杂标签(里面有子标签)-->
                    <xs:complexType>
                        <!--书里面的子标签要顺序出现-->
                        <xs:sequence>
                            <!--书名是书的子标签  type表示类型-->
                            <xs:element name='书名' type='xs:string'/>
                            <!--作者是书的子标签  type表示类型-->
                            <xs:element name='作者' type='xs:string'/>
                            <!--售价是书的子标签  type表示类型-->
                            <xs:element name='售价' type='xs:double'/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

根据上面的Schema约束编写XML

<书架 xmlns="http://www.itcast.cn"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.itcast.cn bookSchema.xsd" >
​
    <书>
        <书名>java入门当放弃</书名>
        <作者>詹姆斯高斯林</作者>
        <售价>99.8</售价>
    </书>
​
    <书>
        <书名>java入门当放弃</书名>
        <作者>詹姆斯高斯林</作者>
        <售价>99.8</售价>
    </书>
​
​
    <书>
        <书名>java入门当放弃</书名>
        <作者>詹姆斯高斯林</作者>
        <售价>99.8</售价>
    </书>
​
</书架>

结论

不管是DTD还是Schema约束,约束文件是不会让你写的。

使用任何约束,都需要在XML中引入约束,引入的方式直接复制就可以了。

三、XML文件的DOM4J解析

1、解析方式

DOM:DOM方式的意思是把整个XML文件读取到内存中,然后解析其中的内容。

缺点:如果文件太大,可能导致内存不够用。

优点:可以对整个文档进行增删改查操作。

SAX: 读取一部分到内存中,解析完一部分之后释放内存再读取下一部分。

缺点:无法对整个文档进行增删改查操作。

优点:不占用大量内存,不会出现内存溢出。

2、解析开发包

JAXP: 这个工具是JDK中自带的解析开发包,用的时候不需要另外下载。

DOM4J: 这个开发包是第三方提供的,简单好用,如果使用需要下载jar包。

JSOUP: 这个开发包是用来解析HTML文件的,也可以用来解析XML,需要下载jar包。

百度网盘链接:https://pan.baidu.com/s/1z-0J0dZO-N2Et8E2NkT-8Q
提取码:1111

3、DOM4J解析

3.1 方法介绍

创建解析器对象:
    SAXReader sr = new SAXReader();
解析器读取文件方法:
    Document doc = sr.read(String fileName);
Document的方法:
    getRootElement()            : 获取根元素 
    
节点中的方法: 
    elements()                  : 获取当前元素的子元素
    element(String name)        : 根据元素名获取指定子元素(如果有多个就获取到第一个)
    getName()                   : 获取元素的元素名
    attributeValue(String name) : 获取当前元素下某个属性的值
    elementText(String name)    : 获取指定子元素的文本值,参数是子元素名称
    getText()                   : 获取当前元素的文本值

3.2 代码演示

XML文件

<天气预报>
    <北京>
        <东城区>
            <最高温度>12℃</最高温度>
            <最低温度>-2℃</最低温度>
        </东城区>
        <西城区>
            <最高温度>13℃</最高温度>
            <最低温度>-1℃</最低温度>
        </西城区>
        <顺义区>
            <最高温度>14℃</最高温度>
            <最低温度>-3℃</最低温度>
        </顺义区>
    </北京>
​
​
    <天津 jc="津" level="1.5线">
        <武清区>
            <最高温度>15℃</最高温度>
            <最低温度>2℃</最低温度>
        </武清区>
        <南开区>
            <最高温度>20℃</最高温度>
            <最低温度>6℃</最低温度>
        </南开区>
    </天津>
</天气预报>

java代码

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
​
import java.util.List;
​
public class Test01 {
    public static void main(String[] args) throws DocumentException {
        //1.获取解析器对象
        SAXReader reader = new SAXReader();
        //2.读取文件
        //Document叫文档
        Document document = reader.read("day15\\tqyb.xml");
​
        //获取根元素
        Element rootE = document.getRootElement();
​
        //elements()             : 获取当前元素的子元素
        List<Element> list = rootE.elements();
        //遍历集合
        for (Element element : list) {
            System.out.println(element.getName());
        }
​
        System.out.println("=========================");
​
        //element(String name)    : 根据元素名获取指定子元素(如果有多个就获取到第一个)
        Element e = rootE.element("天津");
        System.out.println(e);
        System.out.println("==========================");
​
        //getName()                : 获取元素的元素名
        System.out.println(e.getName());  //天津
​
        System.out.println("==========================");
        //attributeValue(String name)  : 获取当前元素下某个属性的值
        String value = e.attributeValue("jc");
        System.out.println(value);   //津
        String value2 = e.attributeValue("level");
        System.out.println(value2);  //1.5线
​
        System.out.println("==========================");
        //elementText(String name) : 获取指定子元素的文本值,参数是子元素名称
        //通过‘天津’获取‘武清区’这个子元素
        Element e2 = e.element("武清区");
        //获取武清区最高温度的值
        String s = e2.elementText("最高温度");
        System.out.println(s);   //15℃
​
        System.out.println("==========================");
        //getText()                : 获取当前元素的文本值
        Element e3 = e2.element("最高温度");
        String s3 = e3.getText();
        System.out.println(s3);    //15℃
    }
}

4、XPath演示

4.1 介绍

XPath是路径的表现形式,可以快速的定位XML中的元素。

Node中的两个方法可以使用XPath:

Node是XML中各种类型的父类,比如Node是Element的父类

List selectNodes("表达式")             :使用Xpath作为参数查找多个元素
Node selectSingleNode("表达式")        :使用Xpath作为参数查找某个元素(默认获取第一个)

4.2 Xpath表达式写法

  • 绝对路径表达式方式

以/开始的路径叫绝对路径,绝对路径是根节点开始查询。

  • 相对路径表达式方式

不以/开始的路径叫相对路径,相对路径是相对于当前节点。

  • 全文搜索路径表达式方式

在路径中使用//表示全文搜索,也就是可以忽略中间的层级

  • 谓语条件查询 (了解)

    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Node;
    import org.dom4j.io.SAXReader;
    ​
    import java.util.List;
    ​
    public class Test02 {
        public static void main(String[] args) throws DocumentException {
            //1.获取解析器对象
            SAXReader reader = new SAXReader();
    ​
            //2.读取文件
            Document document = reader.read("day15\\tqyb.xml");
    ​
            //Node表示结点,在XML中所有的类型都属于Node
            //Element是Node的子类
            //Attribute是Node的子类
    ​
            //List selectNodes("xpath表达式")          :使用Xpath作为参数查找多个元素
            //Node selectSingleNode("xpath表达式")        :使用Xpath作为参数查找某个元素(默认获取第一个)
            //绝对路径:
            List<Node> list = document.selectNodes("/天气预报/北京/东城区");
            //遍历集合
            for (Node node : list) {
                System.out.println(node.getName());
            }
            System.out.println("--------------------");
            Node node = document.selectSingleNode("/天气预报/北京/东城区");
            System.out.println(node.getName());
    ​
            System.out.println("====================");
            //相对路径
            //通过东城区获取西城区
            Node node1 = node.selectSingleNode("../西城区");
            System.out.println(node1.getName());
            //通过西城区获取武清区
            Node node2 = node1.selectSingleNode("../../天津/武清区");
            System.out.println(node2.getName());
    ​
            System.out.println("===================");
            //全文搜索
            //获取所有的最高温度
            List<Node> list2 = document.selectNodes("//最高温度");
            for (Node node3 : list2) {
                System.out.println(node3.getText());
            }
            System.out.println("-----------------");
            //获取北京里面所有的最高温度
            List<Node> list3 = document.selectNodes("//北京//最高温度");
            for (Node node3 : list3) {
                System.out.println(node3.getText());
            }
            System.out.println("-----------------");
            //获取东城区的最高温度
            Node node3 = document.selectSingleNode("//东城区//最高温度");
            System.out.println(node3.getText());  //13℃
    ​
            //谓语查询(条件查询)
            System.out.println("=====================");
            Node node4 = document.selectSingleNode("//最高温度[@level='a']");
            System.out.println(node4.getText());   //15℃
    ​
    ​
        }
    }
    • 元素[@属性名=’属性值‘]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值