java回顾之XML和dom4j

java回顾之XML和dom4j

1.XML

1.XML介绍

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

XML是用来传输数据的,不是用来显示数据的。之后学习另外一个HTML是用来显示数据的。

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

XML是W3C的一个语言。

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

2.编写XML

XML不是java的内容,之前的java文件都需要写在src里面,XML不需要写在src里面

person.xml
   <person>
       <name>柳岩</name>
       <age>36</age>
   </person>

3.XML的作用

  1. 用来【存储数据】,作为数据交互的载体,可以传输数据

  2. 可以作为【配置文件】,在框架中会有使用

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 + /
  • 转义字符

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

    <      &lt;
    >     &gt;
    "     &quot;
    '     &apos;
    &     &amp;
    <说说>不要低头,皇冠&lt;会掉&gt;</说说>
  • CDATA区 (了解)

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

    <![CDATA[    
    文本数据
    ]]>

 

2.约束

1.概念

因为XML本身没有预定义标签,可能大家写的XML就会乱七八糟。

约束的作用就是限制XML里面可以写什么。

约束有两种: DTD约束 和 Schema约束。

约束是不会让我们写的,我们是根据约束去写对应的XML!!!

2.DTD约束

  • 介绍

    DTD是一个XML的约束,可以规定XML可用的标签,规定标签出现的次序,规定标签的嵌套方式。

  • DTD约束文档

    bookdtd.dtd

    <!--
       复制内容如下到XML文件中:
           <!DOCTYPE 书架 SYSTEM "bookdtd.dtd">

    -->
    <!--ELEMENT表示元素  书架是根标签   (+)书架里面子元素是书 书可以有一本或多本-->
    <!ELEMENT 书架 (+)>
           <!--书也是一个元素 书里面的子元素是 书名 作者  售价-->
           <!ELEMENT 书 (书名,作者,售价)>
            <!--书名也是一个元素  书名是一个文本-->
           <!ELEMENT 书名 (#PCDATA)>
           <!--作者也是一个元素  书名是一个文本-->
           <!ELEMENT 作者 (#PCDATA)>
           <!--售价也是一个元素  书名是一个文本-->
           <!ELEMENT 售价 (#PCDATA)>
  • DTD引入方式

    1.内部DTD,在XML文档内部嵌入DTD,只对当前XML有效
    <!DOCTYPE 根元素 [...//具体语法]>

    2.外部DTD—本地DTD
    <!DOCTYPE 根元素 SYSTEM "bookshelf.dtd"> "bookshelf.dtd"表示dtd名称

    3.外部DTD—公共DTD
    <!DOCTYPE 根标签 PUBLIC "dtd的名字" "网络上的位置">

    引入一定不会让你写,现成的语句你复制就可以了。

  • 按照上面的dtd约束编写XML

    <!DOCTYPE 书架 SYSTEM "bookdtd.dtd">
    <书架>
       <>
           <书名>java从入门到放弃</书名>
           <作者>吴彦祖</作者>
           <售价>99.8</售价>
       </>
    </书架>
  • DTD约束的符号介绍

    *       表示可以出现任意次
    +       表示可以出现一次或多次
    ?       表示可以出现0次或1次

    ,       表示需要顺序出现
    |       表示或

 

3.Schema约束

  • 介绍

    • Schema约束是约束界的龙头老大,可以对数据类型做更加精准的限制。在后期xml中更多的使用Schema约束。

    • Schema约束的文件名以.xsd结尾。

  • Schema约束文档

    • bookschema.xsd

    <?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.itheima.cn"
           elementFormDefault="qualified">

       <!--这是一个元素  名字叫书架-->
       <xs:element name='书架'>
           <!--这是一个嵌套元素-->
           <xs:complexType>
               <!--sequence表示顺序  子元素最多出现2次-->
               <xs:sequence maxOccurs='2'>
                   <!--子元素的名字叫 -->
                   <xs:element name='书'>
                       <!--也是一个嵌套元素-->
                       <xs:complexType>
                           <!--子元素也是顺序出现 可以出现最少1次  最多无限-->
                           <xs:sequence minOccurs="1" maxOccurs="unbounded">
                               <!--书的子元素  书名 是字符串类型-->
                               <xs:element name='书名' type='xs:string'/>
                               <!--书的子元素  作者 是字符串类型-->
                               <xs:element name='作者' type='xs:string'/>
                               <!--书的子元素  售价 是小数类型-->
                               <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.itheima.cn"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.itheima.cn yueshu/bookSchema.xsd">

       <>
           <书名>java从入门到放弃</书名>
           <作者>吴彦祖</作者>
           <售价>99.8</售价>
       </>

       <>
           <书名>数据库从入门到跑路</书名>
           <作者>曹琪</作者>
           <售价>999.8</售价>
       </>

    </书架>
  • 结论

    • 我们是根据约束去写XML, 我们不会写约束,约束是框架提供的或者是公司提供的

3.DOM4J

1.解析方式

DOM: 把整个XML文件作为树的方式直接加载到内存中。

优点:整个文件在内存中,可以对文件的内容进行增删改查

缺点:对内存的要求太大,可能导致内存溢出

SAX: 边读取边操作,把整个树分开,读到哪里就操作到哪里,操作完就释放内存,再去读下一段内容

优点:不占用太大的内存,不会出现内存问题

缺点:只能查询对应的内容,不能对元素做增删改操作。

2.解析开发包

JAXP:是java自带的解析开发包。使用的时候不需要导入jar包

DOM4J: 4-->for J-->java。是非常优秀的第三方开发包。在使用之前需要导入jar包。

JSOUP: 是专门用于解析HTML的技术。

3.DOM4J解析

  • 方法介绍

    创建解析器对象:
    SAXReader sr = new SAXReader();
    解析器读取文件方法:
    Document doc = sr.read(String fileName);
    Document的方法:
    getRootElement() : 获取根元素

    节点中的方法:
    elements()     : 获取当前元素的子元素
    element(String name) : 根据元素名获取指定子元素(如果有多个就获取到第一个)
    getName() : 获取元素的元素名
    attributeValue(String name) : 获取当前元素下某个属性的值
    elementText(String name) : 获取指定子元素的文本值,参数是子元素名称
    getText() : 获取当前元素的文本值
  • 代码演示

  • public class Demo01DOM4J {
        public static void main(String[] args) throws DocumentException {
            //获取解析器对象
            SAXReader reader = new SAXReader();
            //读取文件
            Document document = reader.read("day22_2\\tianqi.xml");
    
            //获取根元素
            Element root = document.getRootElement();
    
            //elements()             : 获取当前元素的子元素
            List<Element> elements = root.elements();
            //遍历集合
            for (Element e : elements) {
                System.out.println(e);
            }
    
            System.out.println("---------------------------");
            //element(String name)    : 根据元素名获取指定子元素(如果有多个重名就获取到第一个)
            Element e = root.element("上海");
            System.out.println(e);
    
            System.out.println("---------------------------");
            //getName()                : 获取元素的元素名
            System.out.println(root);
            System.out.println(root.getName());
    
            //--------------------------
            //获取北京里面的最高温度这个元素
            Element maxwd = root.element("北京").element("温度").element("最高温度");
            System.out.println(maxwd.getName());  //最高温度
            //--------------------------
            System.out.println("---------------------------");
    
    
            //attributeValue(String name)  : 获取当前元素下某个属性的值
            String s = root.element("北京").attributeValue("province");
            System.out.println(s);
    
            System.out.println("---------------------------");
    
    
    
            //elementText(String name) : 获取指定子元素的文本值,参数是子元素名称
            //获取北京的最高温度
            Element wd = root.element("北京").element("温度");
            //获取温度里面子元素最高温度的值
            String s1 = wd.elementText("最高温度");
            System.out.println(s1);
    
            //getText()                : 获取当前元素的文本值
            System.out.println("-----------------------------");
            //获取北京的最高温度
            Element mwd = root.element("北京").element("温度").element("最高温度");
            //获取当前元素的值
            String s2 = mwd.getText();
            System.out.println(s2);
    
    
        }
    } 

    4.XPath演示

    • 介绍

      • 刚才我们发现,DOM4J原始写法太过于复杂,复杂在需要一层一层的获取子元素。

      • XPath的作用是快速的直接定位到目标元素。

      • XPath是一种路径的写法,下面的两个方法中支持XPath的写法。

      • Node叫做是节点,DOM里面所有的类型都是Node的子类

        • 比如Document Element Attribute 都是 Node的子类

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

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

      • 绝对路径表达式方式

        • 以/开头的路径就是绝对路径

        //  以单/开头叫绝对路径,绝对路径必须从根元素开始写
        //获取天气预报中上海子元素
        List<Element> list = document.selectNodes("/天气预报/上海");
        //遍历集合
        for (Element element : list) {
           System.out.println(element);
        }

        System.out.println("---------------------");
        //Node selectSingleNode("表达式")     :使用Xpath作为参数查找某个节点(默认获取第一个)
        //获取天气预报中第一个上海子元素
        Node node = document.selectSingleNode("/天气预报/上海");
        System.out.println(node);
      • 相对路径表达式方式

        • 不以单/开头的路径叫相对路径,相对路径相对的是当前元素

        //不以单/开头的路径叫相对路径,相对于当前元素
        Node node1 = document.selectSingleNode("/天气预报/北京/温度");
        System.out.println(node1);
        //用相对路径的写法获取湿度
        Node node2 = node1.selectSingleNode("../湿度");
        System.out.println(node2);
        System.out.println("------------------------------------------");
        Node node3 = document.selectSingleNode("/天气预报/上海/温度/最高温度");
        Node node4 = node3.selectSingleNode("../../湿度");
        System.out.println(node4.getText()); // 50%
      • 全文搜索路径表达式方式

        • //代表忽略中间的路径,不管中间有多少级

        //全文搜索
        //获取文本中的所有最高温度
        List<Element> list1 = document.selectNodes("//最高温度");
        //遍历集合
        for (Element e : list1) {
           System.out.println(e.getText());
        }
        System.out.println("--------------------------------");
        //获取广州里面的所有最高温度
        List<Element> list2 = document.selectNodes("//广州//最高温度");
        //遍历集合
        for (Element e : list2) {
           System.out.println(e);
        }
        System.out.println("-----------------");
        //获取广州里面的直接的最高温度
        List<Element> list3 = document.selectNodes("//广州/温度/最高温度");
        for (Element e : list3) {
           System.out.println(e);
        }
      • 谓语条件查询 (了解)

        可以对属性进行更精细的判断

        //谓语查询
        List<Element> list4 = document.selectNodes("//最高温度[@level='CC']");
        //遍历集合
        for (Element e : list4) {
           System.out.println(e.getText());
        }

      总结

posted @ 2020-11-01 20:31  springcode  阅读(147)  评论(0编辑  收藏  举报