Xml笔记

1. 认识XML

1.1 什么是XML

 全称:可扩展标记语言(Extensible Markup Language)。是一门标记语言。诞生于1996年(96年发行第一个版本1.0,到了04年更新为1.1版本,但是用的最多是1.0版本),html也是标记语言,xml跟html不同的是xml没有固定的标签,所有的标签都可以自定义。这也是为什么叫它可扩展的原因。什么是标记语言,就是由两对尖括号括起来的语言,<>,学过html都知道。那么它就是用这么一个标记来描述数据的。可以把标记理解为标签。

1.2 XML被用来干什么

 通常,xml被用于信息的记录(配置文件)传递(网络上传输),而非显示数据(html才是显示数据的)。因此xml经常用于充当配置文件。像我们学习框架的时候,是不是会在xml里面写数据库的连接信息,把properties替换掉,阅读性比properties好,properties只是存一些简单的数据,复杂数据用xml存。一说到记录,就会想到数据库,但是数据库比较麻烦,比如我数据库里的数据要想导给你,得先从我电脑上的数据库软件导出一个文件,再把这个文件发给你,但前提是你得有一个数据库软件,再把我给你的文件导进去,而xml其实就是一个文本文件,一个文档。拿到即用,不用什么安装即可使用。

1.3 XML的格式

  1. 第一行必须声明文档信息,用于描述xml的版本和编码方式。必须是要顶格写,不能有空格回车。

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

    在这里插入图片描述
    version是必须的属性,encoding是编码方式,默认是ISO-8859-1,告知解析引擎当前文档使用的字符集,用默认的去解码,上面的指示用utf-8,那么它就用utf-8去解码,否则编码跟解码不一样,就会乱码,所以还要注意你文件的编码是多少。以Notepad++为例,如下图:
    在这里插入图片描述
    所以,你用utf-8去编码,就要用utf-8去解码。但是idea编辑器会根据你的解码是utf-8,编码自动识别为utf-8,从编辑器的右下角就可以查看,如图:
    在这里插入图片描述

    它不单单有version,encoding属性,还有一个属性叫standalone:表示是否独立。如果是是的话,就是yes,standalone="yes",表示这个文件是独立的,不依赖于其他文件。这个属性了解即可。
     因为早期xml想要代替html来展示数据,所以它还可以引入css,这也是了解,如下代码:

    <?xml-stylesheet type="text/css" href="a.css"?>
    
  2. xml有且只有一个根元素。什么是元素,元素,由三部分构成,开始标签+内容+结束标签,这一整个就是一个元素,所谓的根元素,就是这一元素外面没有被其它元素包围。声明信息不算。标签又叫元素,也叫节点。注意下面是错的,存在两个同级别的根元素:

    <?xml version="1.0" encoding="UTF-8"?>
    <haha>
    </haha>
    <aaa>
    </aaa>
    
  3. xml是大小写敏感的。比如<a></A>是错的。

  4. 标签是成对的,而且要正确嵌套。比如下面的代码是非法嵌套。

    <a>
        <aa>
    </a>
    </aa>
    
  5. 属性值要加引号。

  6. 注释的写法:

    <!--  这里是注释 -->
    
  7. DTD和XSD定义语义约束:DTD和XSD是用来规范xml的语法的,文件的格式。因为它过于灵活,想怎么写怎么写,就要有东西来规范一下,有个约束。后面会讲。注意一下:XSD约束其实是Schema约束,文件后缀是.xsd。

  8. 注意:xml的标签可以写中文,但不要这么做。

1.4 激活XML文件

 只要是xml文件,都会在开头写上<?xml version="1.0" encoding="UTF-8"?>这句话,打开编辑器比如idea,我们去新建一个xml文件,可能没有专门的xml文件,就会去新建File,然后取名为xxx.xml,但是这种建立,它的头并没有xml的版本声明以及编码的声明,每次建都要自己写,很麻烦,那有没有一种专门的xml文件,一新建它的头信息就已经写好了,我们就不用写了,答案是有的,以idea为例,首先点击idea左上角的File->Settings,如图:
在这里插入图片描述
点击,然后,如下图:
在这里插入图片描述
按照上面的步骤走,就好了,然后测试一下,点击项目右键,如图:
在这里插入图片描述
这样是不是就有了,去新建就自动有头信息了,就不用每次都去自己写了。

2. DTD和XSD定义语义约束

在讲它之前有个例子:
就是使用XML描述下表:
在这里插入图片描述
那么我们新建一个文件叫scores.xml。描述如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--得有根元素-->
<scores>
    <!--student你也可以写成stu,xml是一个很灵活的语言-->
    <student id="1">
         <name>小明</name>
         <course>数学</course>
         <score>77</score>
    </student>
    <student id="2">
        <name>小美</name>
        <course>语文</course>
        <score>90</score>
    </student>
    <student id="3">
        <name>小爱</name>
        <course>英语</course>
        <score>85</score>
    </student>
     <!--但是这种如果是团队开发,你写的标签名是student,别人写的是stu,都没错,但是当它们合并到一起,就显得有点乱,
取信息不好取,本来student和stu表示一个意思。所以,我们要对它进行约束,统一,比如,根元素必须是scores,
scores里面都是student标签,代表每一个学生对象,student必须有id属性,student标签里面有三个标签,分别是name,course,score。
按照这种格式写,标签名要统一,就是描述表格的时候要按我上面的来就是了。不管谁来写,最终写出来的效果就跟一个人写出来的是一样的。
-->
</scores>

浏览器打开如下:
在这里插入图片描述
因为xml文件写好后,我们需要用java技术来读取它,以后学习框架,框架就会自动的读取我们程序员写的配置文件进行解析,但是它的标签灵活,所以读取麻烦,那么就得用DTD来约束一下。

2.1 DTD

认识DTD

DTD:Document type definition(文档类型定义)
作用:约束文档格式,合法定义文档的结构。说白了,就是规定哪些标签是合法的,哪些是不合法的。
DTD分为外部DTD和内部DTD。内部DTD是在xml文件里定义的,外部DTD是单独的一个DTD文件,那么在xml文件中就要把外部的DTD引入进来,可以把约束文件理解为xml的说明文档。

内部DTD的使用

  1. 内部DTD的定义(内部的DOCTYPE声明):
    语法:<!DOCTYPE 根元素 [元素声明] >。DTD的约束会被包装到DOCTYPE的声明中。注意,这里的根元素不等于根节点,根节点(也叫文档节点)代表的是整个文档document,就是xml文件本身。而根元素(就是一个普通的元素节点)只是xml里面的一个根。注意区分。

  2. 元素声明语法:

    <!ELEMENT 父元素名 (子元素[子元素...])>
    

    括号里面的元素表示的是这个标签它里面可以出现哪些子标签,注意括号里面的是子标签,多个子标签用逗号隔开,但我们在xml中去使用它是,要注意顺序,比如约束文档中(name,age),那么你在xml文件中标签name就要写在age的前面。

  3. 数量词:限制元素出现几次

    • +:表示出现1次或多次,至少一次。
    • ?:出现0次或1次。
    • *:表示出现任意次。
    • 没有前三个修饰的标签表示这个标签必须出现一次。多了不行。
    • |:比如:<!ELEMENT 父标签 ((子标签1|子标签2))>,这代表什么意思呢?表示这两个子标签必须有一个出现在父标签中,但是不能同时出现。
  4. 属性声明语法:

    <!ATTLIST 元素名称 属性名称 属性类型 默认值> 
    

    属性类型如下:
    在这里插入图片描述
    CDATA表示字符类型,表示它是字符串。默认值参数有下列值:
    在这里插入图片描述
    比如我要保证student标签必须要有id属性,就是这么写,如下:

    <!ATTLIST student id CDATA #REQUIRED>
    

现在对上面写的代码进行约束,约束代码如下:

<!DOCTYPE scores [
   <!ELEMENT scores (student+)>
   <!ELEMENT student (name,course,score)>
   <!ELEMENT name (#PCDATA)>
   <!ELEMENT course (#PCDATA)>
   <!ELEMENT score (#PCDATA)>
   <!ATTLIST student id CDATA #REQUIRED>
]>

注意上面的该空格要空格,不然没有效果。然后是PCDATA表示:意思是被解析的字符数据,可把字符数据想象为XML元素的开始标签与结束标签之间的文本,它没有子标签,就是一个纯粹的文本。完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE scores [
   <!ELEMENT scores (student+)>
   <!ELEMENT student (name,course,score)>
   <!ELEMENT name (#PCDATA)>
   <!ELEMENT course (#PCDATA)>
   <!ELEMENT score (#PCDATA)>
   <!ATTLIST student id CDATA #REQUIRED>
]>
<scores>
    <student id="1">
         <name>小明</name>
         <course>数学</course>
         <score>77</score>
    </student>
    <student id="2">
        <name>小美</name>
        <course>语文</course>
        <score>90</score>
    </student>
    <student id="3" >
        <name>小爱</name>
        <course>英语</course>
        <score>85</score>
    </student>
</scores>

在这里插入图片描述
ELEMENT是限制元素的,定义哪些标签合法。ATTLIST是限制属性的,定义哪些属性合法

外部DTD的使用

  1. 创建一个独立的DTD文件。其实dtd文件也是一种特殊的xml文件,因为它有头信息。取名:scores.dtd,内容如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!ELEMENT scores (student+)>
    <!ELEMENT student (name,course,score)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT course (#PCDATA)>
    <!ELEMENT score (#PCDATA)>
    <!ATTLIST student id CDATA #REQUIRED>
    

    我们发现写法其实跟内部的一样,只是外部的DTD不用写<!DOCTYPE scores [罢了。DOCTYPE 只存在于.xml的文件中。接下来就是在xml文件中去使用它。怎么使用呢,如下第2点。

  2. 格式:

    <!DOCTYPE 根元素 SYSTEM "文件名">
    

    所以只需要在xml文件中加上这句话:

    <!DOCTYPE scores SYSTEM "scores.dtd">
    

    在xml中引入dtd文件,就会对xml起到约束作用,那些该写,哪些不该写。这样 ,引入后,xml就会有提示了。到以后学习框架之类的就会明白。但是这种引入属于本地引入,SYSTEM表示system,就是系统的意思,代表本地,如果这个dtd文件在网络上,哪这样写就不对了,格式如下:

    <!DOCTYPE 根元素 PUBLIC "dtd文件名字(随便写)" "dtd的网络路径url">
    

2.2 XSD(Schema约束)

XSD是DTD的升级版,替代者。不仅可以定义xml文档结构,还可以规范文档的内容(比如在xml有这么一个标签<sex>888</sex>,正常来说,sex应该表示性别,哪你写个数字888表示什么意思?我们是不是要对其内容进行限制?那么schema约束就可以完成这件事)。XSD本身也是xml文档,采用xml文档来定义语义约束,比DTD要复杂一点,但是功能强大很多。它是利用标签的父子关系来描述约束信息的

  1. 支持丰富的数据类型。
  2. 允许开发者自定义数据类型。
  3. 可读性强。
  4. 可针对未来需求进行扩展。

 注意你在mybatis看到如下的就是schema约束:
在这里插入图片描述
 像上面这种,它属于在xml文件中引入Schema约束,注意是引入。还有注意,dtd约束和schema约束不能出现在同一个文档中。虽然像上面我们平时都是复制的,不是自己写,但是如果能够看懂,读懂,就行,所以,我们现在就来解读它。现在我有一个a.xml文件,如下图:
在这里插入图片描述
 重点看上面,也就是根标签哪部分,像冒号,xmlns这些都是什么意思呢?用图说话。
在这里插入图片描述
 有了上面的解释,我们来看看spring的配置文件Beans.xml ,如下:
在这里插入图片描述
 一样,用图说话,如下:
在这里插入图片描述
 接下来就是xsd文件的编写语法了,这里就直接粘贴上完整代码了,复制到你们的编辑器去看:
a.xml文件代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<cht:scores xmlns:cht="abc"
			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			xsi:schemaLocation="abc a.xsd">		
    <!--
    abc是我们自己起的,可以随便写,但是想spring这些框架,都是写一个网址,这是因为网址是唯一的,不会重复的,所以,当我们定义多个schema约束时,别名能不能重复?
        答案是肯定不能,这里一般会写公司的网址。
        多个命名空间就有多个xmlns 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 声明当前的xml文件是Schema的一个实例(当前这是一个自定义的xml文件,是被某个Schema文件的约束)
    不是一个Schema文件,如果是一个Schema文件,那么后面的instance就不要加上,你可以看看a.xsd文件它是不是没有instance
    -->
    <cht:student id="1">
         <cht:name>小明</cht:name>
         <cht:course>数学</cht:course>
         <cht:score>77</cht:score>
    </cht:student>
    <cht:student id="2">
        <cht:name>小美</cht:name>
        <cht:course>语文</cht:course>
        <cht:score>90</cht:score>
    </cht:student>
    <cht:student id="3">
        <cht:name>小爱</cht:name>
        <cht:course>英语</cht:course>
        <cht:score>34.2</cht:score>
    </cht:student>
</cht:scores>

a.xsd文件代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<cht:schema xmlns:cht="http://www.w3.org/2001/XMLSchema"
           targetNamespace="abc"
           elementFormDefault="qualified">
    <!-- xmlns:cht表示引入了w3c规范,来规范当前约束文件的语法规则 。这句话是重点-->
    <!-- targetNamespace="abc":表示文档中要定义的元素来自什么命名空间,对应xml里的xmlns:cht="abc"。这句话也能是重点
      上面定义当中xmlns:cht和targetNamespace是重点
    -->
    <!-- elementFormDefault="qualified":表示要求xml文档的每一个元素都要有命名空间指定 -->
    <!-- 主体部分 -->
    <!-- 1.在Schema文件中使用element标签来定义xml中所有可以书写的标签名 -->
    <cht:element name="scores">
        <!-- 2,在scores这个根标签里,有name,course,score这三个子标签,但是不要直接在这里写element,要先分析,它是复杂标签
        ,还是简单标签。简单标签:如果一个标签没有子标签,也没有属性,这个标签是一个简单标签。
                      复杂标签:如果标签拥有属性或者拥有子标签,那么这个标签就是一个复杂标签。
             那么根标签scores就是一个复杂标签,复杂标签就要用complexType来声明当前element(scores)是一个复杂标签
         sequence:表示序列,使用这个标签来定义子标签之间的顺序
         simpleType:来声明当前的element是一个简单标签,如下,但可以不写-->
        <cht:complexType>
            <cht:sequence>
            <!-- minOccurs="1"表示最少出现1次 maxOccurs="unbounded"表示最多可以出现很多次 -->
                <cht:element name="student" minOccurs="1" maxOccurs="unbounded">
                    <!-- student标签依然是复杂标签 -->
                    <cht:complexType>
                        <cht:sequence>
                            <cht:element name="name" type="cht:string">  <!-- type声明该元素的文本必须是字符串 -->
                                <!-- type的取值:cht:decimal,cht:integer,cht:boolean,cht:date,cht:time 
                                element还有一个属性叫default,default就是默认值,fixed就是固定值
                                -->
                                <!-- <simpleType></simpleType> -->
                            </cht:element>
                            <cht:element name="course" type="cht:string"></cht:element>
                            <cht:element name="score" type="cht:double"></cht:element>
                        </cht:sequence>
                        <!-- 定义标签student的id属性 -->
                        <cht:attribute name="id" type="cht:string" use="required"></cht:attribute>
                    </cht:complexType>
                </cht:element>
            </cht:sequence>
        </cht:complexType>
    </cht:element>
</cht:schema>

把我上面的两个a.xml和a.xsd文件复制到你们的编辑器上去测试。

3. XML的解析技术(一种读取方式)

 xml内容写好了,就要对xml进行解析。对xml文件进行操作,包括创建xml,对xml文件进行增删改查。所谓的解析,就是操作xml文档,将文档中的数据读取到内存中。

3.1 DOM(文档对象模型)解析

 是官方(sun公司)提供的解析方式。它的特点是:基于xml树结构(在内存中形成一颗dom树),比较耗资源,适用于多次访问xml。它的读取方式是一次性将xml文档所有内容,加载到内存中,形成一个对象,而对象,肯定是耗内存的。所以它的缺点是浪费内存,优点是读取大量标签的时候,因为这些标签已经在内存中了,所以运行速度较快。它不仅可以处理xml,也可以处理html,比如在学js的时候,就会涉及dom操作,是不是会对里面的节点进行crud操作。
 xml本身有许多节点,有元素节点,文本节点(包括回车空白),属性节点,注释节点,CDATA节点,文档节点。不要以为就只有元素叫节点。难以理解的就是CDATA节点,它的意思是避免内容里有特殊符号,比如尖括号这些,我们可以用<![CDATA[内容]]>把内容包裹起来,如下:

<标签名><![CDATA[I like read <老人与海>]]></标签名>

如果不用CDATA,遇到<,要用&lt;进行转义。

3.2 SAX解析

 相对于上面是官方的,那么这就是民间的解析方式。它的特点是基于事件的解析。这种基于事件解析的消耗资源要少。这种读取方式,根据开发人员的需要,一次将若干个满足条件的标签加载到内存中,所以它可以节省内存。如果读取大量标签信息时,因为要经过多次io流,所以运行效率相当较低,并且它只能读取,不能增删改。

3.3 JDOM解析

 它是一个工具,第三方提供,它开放源代码,比DOM更快,JDOM仅使用具体类而不使用接口。也就是说它提供了很多工具类,你可以拿它来解析。

3.4 JAXP解析

 sun公司提供的解析器,支持dom和sax两种思想,此处了解即可。

3.5 DOM4J解析

 注意,DOM4J的4是for,for就是为了的意思,不是4的英文four,是for,j是java的意思,其实就是一种为java提供解析方式的dom。它也是第三方提供的,开源免费,是JDOM的升级版。性能优异,功能强大,使用接口而不是实现类。像hibernate框架用它来解析xml配置文件。接下来我们使用dom4j来解析xml,如下:首先,创建一个项目,有xml和class类。
在这里插入图片描述
sorce.xml就是上面写的xml代码。
解析xml的入口,是需要拿到一个Document对象。用Document对象来表示xml文件。哪我们对xml文件的操作,就是对Document对象的操作。首先,我们要有dom4j的jar包,它不是jdk提供的,是第三方的,所以我们要去网上下载dom4j的jar包。下载网址:https://mvnrepository.com/artifact/dom4j/dom4j,选择1.6.1版本。然后在项目里新建lib文件夹,把jar包放进去。再对jar包build path,怎么build path?流程:File -> Project Structure -> Modules -> 选中要添加build path的项目 -> Dependencies -> 点击右边的小加号 -> 选择JARs or directories ->选择要添加的外部jar包
在这里插入图片描述
如果像这样,能将其展开,说明build path成功。我们主要用到两个类,它就在org目录下。
在这里插入图片描述
没错,就是DOMReader和SAXReader。DOM和SAX是不是很熟悉。接下来就是开始写代码了。如下代码:

package com.cht;

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

import java.io.File;
import java.util.Iterator;

public class TestXml {
    public static void main(String[] args) throws DocumentException {
        //1. 创建SAXReader对象,用于读写xml文件
        SAXReader reader = new SAXReader();
        //2. 读取xml文件,得到Document对象(这个对象代表整个xml文件,它拥有xml文件的所有信息)
        File xmlFile = new File("src/sorce.xml");
        Document document = reader.read(xmlFile);
        //System.out.println(document);//org.dom4j.tree.DefaultDocument@6d311334 [Document: name file:///D:/Tinghuai Hotel/testxml/src/sorce.xml]
        //3. 利用document获取xml文件里的每个学生的信息
        //3.1 获取根元素
        Element root = document.getRootElement();//元素类型
        //上面是不是拿到根元素了,拿到根元素,哪我怎么获取它的名字呢?很简单,用root.getName()看看是不是scores
        //System.out.println(root.getName());
        //3.2 以根元素为出发点,循环遍历根元素下面的所有学生信息。
        Iterator<Element> iterator = root.elementIterator();
        while (iterator.hasNext()){
            //取出元素
            Element e = iterator.next();
            System.out.println(e.getName());//打印3个student
            //获取id属性,属性可以有多个,只不过我们这里只有一个属性,就是id。那么属性有没有迭代器,是有的。
            //因为我们只有一个属性,所有先不用迭代
            Attribute id = e.attribute("id");//注意,该方法有3个重载方法,参数分别是(int i),(String s),(QName qName)
            //注意上面的,参数是int类型表示第几个属性,string类型表示属性名,QName不管
            System.out.println(id.getName() +"="+id.getValue());
            //获取student的子元素
            Element name = e.element("name");
            Element course = e.element("course");
            Element score = e.element("score");
            System.out.println(name.getName()+"="+name.getStringValue());
            System.out.println(course.getName()+"="+course.getText());
            System.out.println(score.getName()+"="+score.getStringValue());
            //getStringValue()和getText()都可以
            System.out.println("=====================================");
        }
    }
}

执行效果:
在这里插入图片描述
这样是不是成功的把xml信息拿到了呀!!!总结:首先,要拿到Document对象,拿到Document对象再通过该对象拿到根节点,拿到了根节点,就可以用迭代器把下面的元素迭代出来,该迭代的迭代,不用迭代的就不要迭代。

_dom4j_生成xml

上面呢我们是对xml读数据,现在我们是要写数据。把数据写进去,创建一个xml。首先,创建一个类,如下:

package com.cht;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
public class TestXml2 {
	public static void main(String[] args) throws IOException{
		// 1. 通过DocumentHelper生成一个Document对象
		Document doc = DocumentHelper.createDocument(); 
		// 2. 添加并得到根元素
		Element root = doc.addElement("books");
		// 3. 为根元素增加子元素
		Element book = root.addElement("book");
		// 4. 为book元素添加属性,它的返回值也是Element,代表book本身
		book.addAttribute("id", "b01");
		// 5. 为book添加子元素
		Element name = book.addElement("name");
		Element author = book.addElement("author");
		Element price = book.addElement("price");
		// 6. 为子元素添加文本,它的返回值也是Element,其实说白了就是方便去链式编程
		name.addText("PHP from beginners to proficient");
		author.addText("Tomorrow Technology");
		price.addText("30");
		// 7. 将doc输出到xml文件中即可
		Writer writer = new FileWriter(new File("src/books.xml"));
		doc.write(writer);
		// 8. 关闭资源
		writer.close();
		
	}
}

但是这样输出生成的xml却在一行显示,如下:
在这里插入图片描述
那怎么办呢?这就需要一个XMLWinter类了。如下代码:

package com.cht;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import javax.sql.rowset.spi.XmlWriter;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public class TestXml2 {
	public static void main(String[] args) throws IOException{
		// 1. 通过DocumentHelper生成一个Document对象
		Document doc = DocumentHelper.createDocument(); 
		// 2. 添加并得到根元素
		Element root = doc.addElement("books");
		// 3. 为根元素增加子元素
		Element book = root.addElement("book");
		// 4. 为book元素添加属性,它的返回值也是Element,代表book本身
		book.addAttribute("id", "b01");
		// 5. 为book添加子元素
		Element name = book.addElement("name");
		Element author = book.addElement("author");
		Element price = book.addElement("price");
		// 6. 为子元素添加文本,它的返回值也是Element,其实说白了就是方便去链式编程
		name.addText("PHP 从入门到精通");
		author.addText("明日科技");
		price.addText("30");
		//7 格式良好的输出
		OutputFormat format = OutputFormat.createPrettyPrint();//美化格式
		XMLWriter writer = new XMLWriter(new FileOutputStream(new File("src/books.xml")),format);
		writer.write(doc);
		// 8. 关闭资源
		writer.close();
	}
}

从数据库里获取数据写入到xml中

这个无非就是从数据库获取list类型的数据,还是一上面学生为例,但此时就不去访问数据库了,自己写一个list类型的数据模拟一下即可,我们要有一个实体类,和一个测试类,如下结构:
在这里插入图片描述

Student代码如下:

package com.cht;
public class Student {
	private String id;
	private String name;
	private String course;
	private String score;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getCourse() {
		return course;
	}
	public void setCourse(String course) {
		this.course = course;
	}
	public String getScore() {
		return score;
	}
	public void setScore(String score) {
		this.score = score;
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", course=" + course
				+ ", score=" + score + "]";
	}
}

TestStudent代码如下:

package com.cht;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public class TestStudent {
	public static void main(String[] args) throws IOException{
		//1. 将这些数据备份为xml文件
		//查询所有的数据为一个list集合,泛型Student
		List<Student> list = selAll();
		//System.out.println(list);
		//[Student [id=1, name=小米, course=数学, score=76], Student [id=2, name=小美, course=语文, score=90]]
		// 2. 将list中的数据输出到一个xml文件中
		writeStudent(list);
	}
	private static void writeStudent(List<Student> list) throws IOException {
		// TODO Auto-generated method stub
		Document doc = DocumentHelper.createDocument();
		Element root = doc.addElement("scores");
		//循环根元素添加子元素
		for (Student stu : list) {
			Element e = root.addElement("student");
			e.addAttribute("id", stu.getId());
			Element name = e.addElement("name");
			Element course = e.addElement("course");
            Element score = e.addElement("score");
            name.addText(stu.getName());
            course.addText(stu.getCourse());
            score.addText(stu.getScore());
		}
		//输出到文件中
		OutputFormat format = OutputFormat.createPrettyPrint();
		XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(new File("src/sorce1.xml")),format);
		xmlWriter.write(doc);
		xmlWriter.close();
	}
	//查询所有的学生
	private static List<Student> selAll() {
		// TODO Auto-generated method stub
		//模拟数据库
		List<Student> list = new ArrayList();
		Student stu = new Student();
		Student stu1 = new Student();
		stu.setId("1");
		stu.setName("小米");
		stu.setCourse("数学");
		stu.setScore("76");
		stu1.setId("2");
		stu1.setName("小美");
		stu1.setCourse("语文");
		stu1.setScore("90");
		list.add(stu);
		list.add(stu1);
		return list;
	}
}

执行main方法,就会在项目中看到scorce1.xml文件啦!

在这里插入图片描述
这样就成功的把数据库里的东西读出来了。以上就是了解,因为在开发过程中,解析xml文档不需要开发人员手动去写。比如框架,它会写好约束文档,并且会自动的封装xml的读取,我们只需要引入约束文档,然后把xml文件写出来即可。

3.6 Jsoup解析

 jsoup不仅可以解析html,也可以解析xml,要用它,一样要导入jar包,去maven库搜索jsoup版本1.11.3即可。

package com.cht;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class JsoupDemo {
	public static void main(String[] args) throws IOException {
		//1. 获取Document对象(有三种方式)
		String path = JsoupDemo.class.getClassLoader().getResource("a.xml").getPath();
		//1.1 解析xml文档,加载文档进内存,形成dom树,形成的dom数就是Document对象。utf-8要与文件的编码一致
		Document doc = Jsoup.parse(new File(path), "utf-8");
		//System.out.println(doc); 打印的doc是字符串形式的html
		//2. 获取元素(Element)对象
		Elements elementsByTag = doc.getElementsByTag("cht:name");//获取标签为name的元素,返回的是Elements,是个复数,我们的xml中一共有3个name标签,那么
		//这里面是不是有个name元素,把它当做ArrayList<Element>来使用
		//System.out.println(elementsByTag.size());// 答案是3
		//3. 获取第一个name的Element对象
		Element element = elementsByTag.get(0);
		//4. 获取数据
		String name = element.text();
	}
}
  1. Jsoup:
    parse:解析html或xml,返回Document。
      parse(File in,String charsetName)
      parse(String html):解析html或xml字符串的。
      parse(URL url,int timeoutMillis):通过网络路径获取指定的html或xml的文档对象,timeoutMillis是超时时间。
  2. Document: 可获取Element对象,它是继承于Element对象的。
    getElementsByTag(String tagName):根据标签的名称获取元素对象的集合。
    getElementsByAttribute(String key): 根据属性名称获取元素对象集合。
    getElementsByAttributeValue(String key,String value): 根据属性名和属性值获取元素的集合。
    getElementsById(String id): 根据id属性值获取唯一的element对象。
  3. Element: 元素对象。
    用它获取子元素对象,所以像上面第2点里的4个方法都能用。
    获取属性值:String attr(String key):根据属性名称获取属性值,这里的key不区分大小写。
    获取文本内容:String text()
    获取标签体的所以内容(包括子标签的字符串内容):String html()
  4. Node: 节点对象:是Document和Element的父类。
  5. 快捷查询方式之selector:选择器
    Elements select(String cssQuery):cssQuery是css选择器,比如#id,[attr],*,这些都是css选择器,具体去网上查找。
    快捷查询方式之XPath:是一门在xml文档中查找信息的语言。使用Jsoup的Xpath需要额外导入jar包(JsoupXpath-0.3.2.jar),XPath语法会有专门一章来说。

xml和html的区别

  1. xml重点是传输,存储数据,而html是展示数据的,作为网页的。因为xml的灵活可扩展性作为网页肯定不行,它通常是作为配置文件的,这样对于数据也非常清晰。
  2. html是一个事先约束好的文档语言,标签不能随便写。而xml的标签你爱写啥写啥。
  3. HTML标签对于英文字母的大小写是忽略不计的,而xml就会严格区分大小写。
  4. html标签中属性值可以有引号,也可以不用引号,但是xml的属性值必须要有引号(双单引号都行)。
  5. html标签你可以省略</p>或者</li>之类的结束标记,语法比较松散,在xml中,是绝对不能省略结束标记的,要么你自闭合,比如<br/>。语法比html严格。
  6. html和xml都遵循w3c规范,w3c翻译过来是世界万维网联盟,它是一个组织,像Schema文件的书写规则都是由W3C组织定义的。
  7. xml是html的一种补充,不是来替换html的(早期是,现在不是)。是先有html再有xml。

DTD约束和XSD约束的区别

  1. DTD约束xml的时候,不能对xml中的数据类型做详细的限定。而XSD比DTD更加的细致,比如对数字区间的限定,限定数字必须是1到100之间的。
  2. DTD约束有自己的语法,书写时必须遵守DTD的语法,而书写Schema文件的时候,它的语法跟写xml文件的一样,它本身也是xml文件。
  3. 一个xml文件中只能引入一个DTD文件约束,而无法通过多个DTD文件来约束同一个xml文件。但是可以引入多个Schema约束。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值