自制笔记 | Java基础——xml(持续更新...)

概述

配置文件是用来保存程序在运行时需要的一些参数

常见的配置文件:txt、properties、xml

三种配置文件的优缺点:

txt:
优点:没有优点
缺点:不利于阅读

properties:
优点:键值对形式易于阅读、解析简单
缺点:无法配置一组一组的数据(例如有多个用户时,一个键就会对应多个值)

XML:
优点:易于阅读、可以配置成组出现的数据
缺点:解析比较复杂

配置文件的选择:数据量较少,一个键只对应一个值,使用properties;数据量较多,使用xml

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

标记语言:通过标签来描述数据的一门语言(标签有时我们也将其称之为元素)
可扩展:标签的名字是可以自己定义的

XML作用:

① 用于进行存储数据和传输数据
② 作为软件的配置文件

语法规则:

① XML文件的后缀名为:xml
② 文档声明必须是第一行

<?xml version="1.0" encoding="UTF-8" ?>
version:XML默认的版本号码、该属性是必须存在的
encoding:本XML文件的编码

标签(元素)规则:

① 标签由一对尖括号和合法标识符组成:<name></name>,必须存在一个根标签,有且只能有一个
② 标签必须成对出现,有开始,有结束:<name></name>
③ 特殊的标签可以不成对,但是必须有结束标记,如:<br/>
④ 标签中可以定义属性,属性和标签名空格隔开,属性值必须用引号引起来<student id = "1"></student>
⑤ 标签需要正确的嵌套

其他组成:

① XML文件中可以定义注释信息:<!-- 注释内容 -->
② XML文件中可以存在以下特殊字符:

&lt;:< 小于
&gt;:> 大于
&amp;: & 和号
&apos;:’ 单引号
&quot;:" 引号

③ XML文件中可以存在CDATA区:<![CDATA[...内容...]]>,CDATA区里的内容会被当做普通的文本来进行解析

示例:

<?xml version="1.0" encoding="UTF-8" ?>
<students>
    <student id="1">
        <name><![CDATA[   <<<>>>>  ]]></name>
    </student>
</students>

文档约束

问题:由于XML文件可以自定义标签,导致XML文件可以随意定义,程序在解析的时候可能出现问题

文档约束:是用来限定xml文件中的标签以及属性应该怎么写。以此强调约束程序员必须按照文档约束的规定来编写xml文件

文档约束的分类:

① DTD
② schema

这两个文档约束了解就行,因为这个文档一般是软件或者别人已经写好的,我们只需要会按照对应的要求写XML文件就行

1.DTD

DTD的使用:

需求:利用DTD文档约束,约束一个XML文件的编写

分析:

① 编写DTD约束文档,后缀必须是**.dtd**

<!ELEMENT 书架 (书+)>
<!ELEMENT 书 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>

第一行表示根标签(书+表示根标签下的字标签为“书”,且有一个或多个这样的字标签);第二行定义了书这个标签的内容,即有三个子标签(书名、作者、售价);最后三行定义了剩下的三个子标签,表明这三个标签下没有子标签了,但是里面内容是PCDATA(文本数据)

② 在需要编写的XML文件中导入该DTD约束文档
③ 按照约束的规定编写XML文件的内容

DTD引入的三种方式:

① 引入本地dtd(掌握):<!DOCTYPE 根元素名称 SYSTEM 'DTD文件的路径'>
② 在xml文件内部引入(了解):<!DOCTYPE 根元素名称[dtd文件内容]>
③ 引入网络dtd(了解):<!DOCTYPE 根元素的名称 PUBLIC "DTD文件名称" "DTD文档的URL">

示例:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE 书架 SYSTEM 'book.dtd'>
<书架>
    <>
        <书名>Java从入门到起飞</书名>
        <作者>高斯林</作者>
        <售价>300.78</售价>
    </>
    
    <>
        <书名>别吃别吃</书名>
        <作者>thehsy</作者>
        <售价>2000</售价>
    </>
</书架>

DTD的作用:可以约束XML文件的编写

DTD的问题:不能约束具体的数据类型

2.schema

schema可以约束具体的数据类型,约束能力上更强大

schema本身也是一个xml文件,本身也受到其他约束文件的要求,所以编写的更加严谨

schema

schema的使用:

需求:利用schema文档约束,约束一个XML文件的编写

分析:

① 编写schema约束文档,后缀必须是**.xsd**
② 在需要编写的XML文件中导入该schema约束文档
③ 按照约束内容编写XML文件的标签

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.itcast.cn/"
           elementFormDefault="qualified">
    <xs:element name="书架">
        <xs:complexType>
            <xs:sequence maxOccurs="unbounded">
                <xs:element name="">
                    <xs:complexType>
                        <xs:sequence>
                            <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文件被谁约束;第三行表示如果别人想要让这个schema文件去约束xml,那么这个xml文件必须要使用到这个地址,这个地址可以理解是一个名字

element表示一个标签,而最外面的element就是根标签;complexType表示当前的标签是一个复杂的标签,即含有其他标签;sequence表示该标签里的内容是有顺序的,必须按照这个顺序来编写;maxOccurs表示最大出现次数,而unbounded表示无上限

最简单的引用方式:直接使用刚才的地址

<?xml version="1.0" encoding="UTF-8" ?>
<书架 xmlns="http://www.itcast.cn/">
    <>
        <书名>别吃别吃</书名>
        <作者>theshy</作者>
        <售价>2800</售价>
    </>
</书架>

解析

XML解析就是使用程序读取XML中的数据

两种解析方式:

① SAX解析
DOM解析

SAX和DOM的优缺点:

① SAX:不会把整体的xml文件都加载到内存,而是从上往下逐行进行扫描(目前不常用)
缺点:只能读取,不能添加,不能删除
优点:因为它是逐行扫描不需要把整体的xml文件都加载到内存,所以它可以解析比较大的xml文件

② DOM:会把整体的xml文件都加载到内存
会把这个整体在内存中形成一个树形结构,我们可以通过这个树形结构去解析xml文件
优点:可以读取,可以添加,可以删除,可以做任何事情
缺点:需要xml文件全部加载到内存,所以不能解析非常大的xml文件(但是目前的内存都很大,所以不需要考虑这个问题)

Dom常见的解析工具:

名称说明
JAXPSUN公司提供的一套XML的解析的API
JDOMJDOM是一个开源项目,它基于树形结构,利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作
Dom4j是JDOM的升级品,用来读写XML文件。具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,Hibernate也用它来读写配置文件
jsoup功能强大DOM方式的XML解析开发包,尤其对HTML解析更加方便

DOM解析文档对象模型:

<?xml version="1.0" encoding="UTF-8" ?>
<students>
    <!--第一个学生信息-->
    <student id="1">
        <name>张三</name>
        <age>23</age>
    </student>
    <!--第二个学生信息-->
    <student id="2">
        <name>李四</name>
        <age>24</age>
    </student>
</students>

image-20240309120539770

Document对象:整个xml文档
Element对象:标签
Attribute对象:属性
Text对象:文本内容

其中Element、Attribute和Text的共同父类是Node对象

案例:使用Dom4j解析出XML文件

需求:使用Dom4j把一个XML文件的数据进行解析

分析:

① 下载Dom4j框架,官网下载
② 在项目中创建一个文件夹:lib
③ 将对应jar包复制到lib文件夹
④ 将这一jar包添加为库
④ 在类中导包使用

得到Document对象:

SAXReader类:

构造器 / 方法说明
public SAXReader()创建Dom4j的解析器对象
Document read(File file)加载XML文件成为Document对象

Document类:

方法名说明
Element getRootElement()获取根元素对象

Dom4j解析XML的元素、属性、文本:

方法名说明
List<Element> elements()得到当前元素下所有子元素
List<Element> elements(String name)得到当前元素下指定名字的子元素返回集合
Element element(String name)得到当前元素下指定名字的子元素,如果有很多名字相同的返回第一个
String getName()得到元素名字
String attributeValue(String name)通过属性名直接得到属性值
String elementText(子元素名)得到指定名称的子元素的文本
String getText()得到文本

案例代码:

public static void main(String[] args) throws InterruptedException, DocumentException {
    //1.创建解析器对象
    SAXReader saxReader = new SAXReader();
    //2.利用解析器去读取xml文件,并返回文档对象
    File file = new File("src\\p2\\a.xml");
    Document document = saxReader.read(file);
    //3.自己解析的时候,一定要一层一层地解析
    Element rootElement = document.getRootElement();
    //4.获取根标签的子标签
    List<Element> elements = rootElement.elements();
    for (Element element : elements) {
        //5.继续获取里面的内容

        //属性id
        Attribute id = element.attribute("id");
        String idValue = id.getText();

        //标签name
        Element name = element.element("name");
        String nameValue = name.getText();

        //标签age
        Element age = element.element("age");
        String ageValue = age.getText();

        System.out.println(idValue + ", " + nameValue + ", " + ageValue);
    }
}

检索

XPath在解析XML文档方面提供了独树一帜的路径思想,更加优雅、高效

XPath使用路径表达式来定位XML文档中的元素节点或属性节点

示例:

① / 元素 / 子元素 / 孙元素
② // 子元素 // 孙元素

案例:使用Xpath检索出XML文件

需求:使用Dom4j把一个XML文件的数据进行解析

分析:

① 导入jar包(dom4j和jaxen),Xpath技术依赖Dom4j技术
② 通过dom4j的SAXReader获取Document对象
③ 利用XPath提供的API,结合XPath的语法完成选取XML文档元素节点进行解析操作
④ Document中与XPath相关的API如下:

方法名说明
Node selectSingleNode("表达式")获取符合表达式的唯一元素
List<Node> selectNodes("表达式")获取符合表达式的元素集合

注意:对于selectSingleNode这个方法来说,如果目标对象有多个,则选取第一个

Xpath的四大检索方案:

① 绝对路径
② 相对路径
③ 全文检索
④ 属性查找

1.绝对路径

采用绝对路径获取从根节点开始逐层的查找 /contactList/contact/name 节点列表并打印信息

方法名说明
/ 根元素 / 子元素 / 孙元素从根元素开始,一级一级向下查找,不能跨级

示例:

public static void main(String[] args) throws InterruptedException, DocumentException {
    //1.创建解析器对象
    SAXReader saxReader = new SAXReader();
    //2.利用解析器去读取本地的xml文件,并返回文档对象
    Document document = saxReader.read(new File("src\\p2\\a.xml"));
    //然后就可以利用xpath方式来进行快速检索
    List<Node> list = document.selectNodes("/students/student/name");
    for (Node node : list) {
        System.out.println(node.getText());
    }

    Node node = document.selectSingleNode("/students/student/name");
    System.out.println(node.getText());
}

2.相对路径

先得到根结点contactList,再采用相对路径获取下一级contact节点的name子节点并打印信息

方法名说明
./ 子元素 / 孙元素从当前元素开始,一级一级向下查找,不能跨级

示例:

public static void main(String[] args) throws InterruptedException, DocumentException {
    //1.创建解析器对象
    SAXReader saxReader = new SAXReader();
    //2.利用解析器去读取本地的xml文件,并返回文档对象
    Document document = saxReader.read(new File("src\\p2\\a.xml"));
    //然后就可以利用xpath方式来进行快速检索
    Element rootElement = document.getRootElement();
    //相对于自己去往下查找
    Element element = (Element) rootElement.selectSingleNode("./student/age");
    System.out.println(element.getName());
    System.out.println(element.getText());
}

3.全文检索

直接全文搜索所有的name元素并打印

方法名说明
// contact找contact元素,无论元素在哪里
// contact / name找contact,无论在哪一级,但name一定是contact的子节点
// contact // namecontact无论在哪一级,name只要是contact的子孙元素都可以找到
public static void main(String[] args) throws InterruptedException, DocumentException {
    //1.创建解析器对象
    SAXReader saxReader = new SAXReader();
    //2.利用解析器去读取本地的xml文件,并返回文档对象
    Document document = saxReader.read(new File("src\\p2\\a.xml"));
    //全文检索
    List<Node> list1 = document.selectNodes("//name");
    for (Node node : list1) {
        System.out.println(node.getText());
    }

    List<Node> list2 = document.selectNodes("//student/name");
    for (Node node : list2) {
        System.out.println(node.getText());
    }

    List<Node> list3 = document.selectNodes("//student//name");
    for (Node node : list3) {
        System.out.println(node.getText());
    }
}

4.属性查找

在全文中搜索属性,或者带属性的元素

方法名说明
//@属性名查找属性对象,无论是哪个元素,只要有这个属性即可
//元素[@属性名]查找元素对象,全文搜索指定元素名和属性名
//元素[@属性名=‘值’]查找元素对象,全文搜索指定元素名和属性名,并且属性值相等
public static void main(String[] args) throws InterruptedException, DocumentException {
    //1.创建解析器对象
    SAXReader saxReader = new SAXReader();
    //2.利用解析器去读取本地的xml文件,并返回文档对象
    Document document = saxReader.read(new File("src\\p2\\a.xml"));
    //查找属性和带属性查找
    //查属性
    List<Node> list1 = document.selectNodes("//@id");
    for (Node node : list1) {
        System.out.println(node.getText());
    }

    //查的是带有指定属性的标签
    List<Node> list2 = document.selectNodes("//student[@id]");
    for (Node node : list2) {
        System.out.println(node.getName());
    }

    //查的是带有指定属性值的标签
    List<Node> list3 = document.selectNodes("//student[@id='1']");
    for (Node node : list3) {
        System.out.println(node.getName());
    }
}
  • 20
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值