Java学习路线(26)——XML与设计模式

news2024/11/23 6:34:53

一、XML

(一)XML的概念: XML是可扩展标记语言(Extensible Markup Language),一种数据表示形式,可以描述非常复杂的数据结构,常用于传输和存储数据。

(二)XML的特点

  • XML的数据是纯文本形式的,默认采用UTF-8编码
  • 可嵌套

(三)XML使用场景: XML内容经常当做消息进行网络传输,或作为配置文件用于存储系统信息。

(四)XML语法

1、文件格式: 【xxx_xxx.xml】
2、文档声明(必须在第一行):

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

3、标签规则

  • 标签是由一对闭合标签(如<src></src>)组成,其中根标签有且只有一个。
  • 特殊标签如单闭合标签,则必须有结束标记(如<br/>)
  • 标签可定义属性,属性和标签名用空格隔开,属性值必须用引号进行赋值。(如<student id=“1”></student>)
  • 注释: 采用 【<!-- xxxx -->】的格式
  • 正文中的尖括号可能会与标签发生冲突,所以需要用特殊字符代替尖括号,特殊字符格式:【&xxxx;】
特殊字符被代替字符
&lt<
&gt>
&amp&
&apos
&quot"
  • XML数据区CDATA: 【<![CDATA[ … ]]】

(1)XML示例

<?xml version="1.0" encoding="UTF-8" ?>
<!--根标签只有一个-->
<student>
    <name>病态王子</name>
    <sex></sex>
    <hobby>傲娇</hobby>
    <info>
        <age>25</age>
        <addr>中国</addr>
    </info>
    <!-- 尖括号可能会发生冲突,所以需要用特殊字符代替尖括号 -->
    <sql>
        select id from user where age &gt; 20;
        <![CDATA[
            select * from user where age < 18;
        ]]>
    </sql>
</student>

(2)XML浏览器解析结果

<!-- 根标签只有一个 -->
<student>
<name>病态王子</name>
<sex>男</sex>
<hobby>傲娇</hobby>
<info>
<age>25</age>
<addr>中国</addr>
</info>
<!--  尖括号可能会发生冲突,所以需要用特殊字符代替尖括号  -->
<sql>
select id from user where age > 20;
<![CDATA[ select * from user where age < 18; ]]>
</sql>
</student>

(五)文档约束

**1、概念:**文档约束是用来限定xml文件中的标签以及属性的写法。

2、分类:
(1)DTD

DTD约束文档xxx.dtd

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

编写xml导入DTD文档

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE 书架 SYSTEM "xxx.dtd"

DTD约束的优缺点

  • 优点: 可以约束XML文件的编写
  • 缺点: 不能约束具体数据类型

(2)schema

概念: schema是一种强约束XML,本身也受到其他约束文件的要求

使用步骤

  • 1、编写schema约束文档,文档名为 【xxx.xsd】
  • 2、XML导入schema约束文档

text.xsd

<?xml version="1.0" encoding="UTF-8" ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.itcast.cn"
        elementFormDefault="qualified" >
<!--targetNamespace:声明约束文档的地址(命名空间) -->
    <element name="书架">
<!--        子元素-->
        <complexType>
            <sequence maxOccurs="unbounded">
                <element name="">
                    <complexType>
                        <sequence>
                            <element name="书名" type="string"/>
                            <element name="作者" type="string"/>
                            <element name="售价" type="double"/>
                        </sequence>
                    </complexType>
                </element>
            </sequence>
        </complexType>
    </element>
</schema>

XML引入schema约束

<?xml version="1.0" encoding="UTF-8" ?>
<!--导包itcast 与 schema对象 -> 引入约束文件 -->
<书架 xmlns="http://www.itcast.cn"  
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn text.xsd">
    <>
        <书名>《红楼梦》</书名>
        <作者>曹雪芹</作者>
        <售价>20.0</售价>
    </>
</书架>

二、XML解析

(一)概念: XML解析是使用程序读取XML中的数据。

(二)解析方式:
1、SAX解析
2、DOM解析

(1)DOM解析文档对象流程

  • 读取文档进入内存,根节点为Document对象
  • XML根节点为第 2 层节点
  • 元素标签为第 3 层节点Element对象
  • 属性标签为第 4 层节点Attibute对象
  • 文本内容为第 5 层节点Text对象

在这里插入图片描述

(三)常见解析工具

工具说明
JAXPSUN公司提供的一套XML解析API
JDOMJDOM基于树形结构,利用纯JAVA技术对XML文档实现解析、生成、序列化以及其他多种操作
dom4jJDOM puls,用来读写XML文件 。具有性能好、功能强和易使用的特点。
jsoup功能强大DOM方式的XML解析开发包,针对HTML解析更加方便

(四)使用Dom4j解析XML

1、使用流程

  • 下载jar包:dom4j-2.1.1.jar
  • 导入jar包
  • 使用jar包

2、Dom4j解析
(1)获取Document对象

构造器/方法说明
SAXReader()创建Dom4j的解析器
Document read(String url)加载XML成为Document对象

(2)获取根元素对象

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

(3)Element元素对象API

方法说明
List<Element> elements()获取当前元素下所有子元素
List<Element> elements(String name)获取当前元素下指定名字的所有子元素
Element element(String name)获取当前元素下指定名字的第一个子元素
String getName()获取元素名称
String attributeValue(String name)根据属性名获取属性值
String elementText(子元素名)获取指定名称的子元素文本
String elementTextTrim(子元素名)获取指定名称的子元素文本并去除前后空格
String getText()获取文本
String attributeValue(属性名)获取属性值
    @Test
    public void parseData() throws DocumentException {
        //1、创建解析器
        SAXReader reader = new SAXReader();

        //2、XML加载
//        Document document = reader.read("D:\\JavaBase\\JavaSEpro\\src\\text.xml");
        //默认在src寻找对应文件名称的文件进行加载
        Document document = reader.read(Dom4JParseDemo.class.getResourceAsStream("/text.xml"));

        //3、获取根元素
        Element root = document.getRootElement();
        System.out.println("根元素:"+root.getName());

        //4、子元素(一级)
        List<Element> elements = root.elements();
        System.out.println("===============一级子元素==============");
        for (Element e :elements) {
            System.out.println(e.getName());
        }

        //5、获取指定元素以及元素值
        System.out.println("===============指定子元素==============");
        System.out.println(root.elementText("name"));
        System.out.println(root.elementTextTrim("hobby"));

        //6、根据元素获取属性值
        Attribute idAttr = root.attribute("id");
        System.out.println(idAttr.getName() + " = " +idAttr.getValue());
    }

/*打印输出*/
根元素:student
===============一级子元素==============
name
sex
hobby
info
sql
===============指定子元素==============
病态王子
傲娇
id = 1

3、文件解析案例

(1)需求: 按照所给的XML文件,将文件数据按指定样式输出
(2)实现:

素材data.xml

<?xml version="1.0" encoding="UTF-8" ?>
<contactList>
    <contact id="1">
        <name>潘金莲</name>
        <gender></gender>
        <email>jinlian@itcast.cn</email>
    </contact>
    <contact id="2">
        <name>武松</name>
        <gender></gender>
        <email>wusong@itcast.cn</email>
    </contact>
    <contact id="3">
        <name>武大郎</name>
        <gender></gender>
        <email>dalang@itcast.cn</email>
    </contact>
</contactList>

实现代码

    @Test
    public void parseDemo() throws DocumentException {
        SAXReader reader = new SAXReader();

        Document document = reader.read(Dom4JParseDemo.class.getResourceAsStream("/data.xml"));

        Element root = document.getRootElement();
        String rootName = root.getName();

        List<Element> memberNode = root.elements();
        for (Element e :memberNode) {
            System.out.println(e.getName() + "{id=" + e.attribute("id").getValue() + ", name=" + e.elementTextTrim("gender") + ", email=" + e.elementTextTrim("email") + "}");
        }
    }

打印输出

contact{id=1, name=女, email=jinlian@itcast.cn}
contact{id=2, name=男, email=wusong@itcast.cn}
contact{id=3, name=男, email=dalang@itcast.cn}

二、XML文件检索

(一)使用工具:Xpath

(二)Xpath使用
1、导入jar包: dom4j和jaxen
2、通过dom4j获取Document
3、利用XPath完成解析操作

(三)相关API

方法说明
Node selectSingleNode(“表达式”)获取符合表达式的唯一元素
List<Node> selectNodes(“表达式”)获取符合表达式的所有元素

(四)三种搜索方式

1、绝对路径搜索

public class XPathDemo {
    @Test
    public void parse1() throws DocumentException {
        //1、解析器
        SAXReader reader = new SAXReader();
        //2、Document对象
        Document document = reader.read(XPathDemo.class.getResourceAsStream("/data.xml"));
        //3、XPath路径搜索

        //绝对路径搜索
        List<Node> nodes = document.selectNodes("/contactList/contact/name");
        
        for (Node node:nodes) {
            Element element = (Element) node;
            System.out.println(element.getTextTrim());
        }
    }
}

/*打印输出*/
潘金莲
武松
武大郎

2、相对路径搜索

public class XPathDemo {
    @Test
    public void parse1() throws DocumentException {
        //1、解析器
        SAXReader reader = new SAXReader();
        //2、Document对象
        Document document = reader.read(XPathDemo.class.getResourceAsStream("/data.xml"));
        //3、XPath路径搜索

        //相对路径搜索
		List<Node> nodes = document.getRootElement().selectNodes("./contact/name");

        for (Node node:nodes) {
            Element element = (Element) node;
            System.out.println(element.getTextTrim());
        }
    }
}

/*打印输出*/
潘金莲
武松
武大郎

3、全文搜索

public class XPathDemo {
    @Test
    public void parse1() throws DocumentException {
        //1、解析器
        SAXReader reader = new SAXReader();
        //2、Document对象
        Document document = reader.read(XPathDemo.class.getResourceAsStream("/data.xml"));
	    //3、Xpath全文检索(只要符合该路径就会匹配)
	    //注意:// --> 代表全文搜索, / --> 代表当前路径,两者可以混合使用
	    //例如 //contect/name 代表全文搜索所有contect的一级元素为name的属性值。
		List<Node> nodes =  document.selectNodes("//name");

        for (Node node:nodes) {
            Element element = (Element) node;
            System.out.println(element.getTextTrim());
        }
    }
}

/*打印输出*/
潘金莲
武松
武大郎

4、属性查找

public class XPathDemo {
    @Test
    public void parse1() throws DocumentException {
        //1、解析器
        SAXReader reader = new SAXReader();
        //2、Document对象
        Document document = reader.read(XPathDemo.class.getResourceAsStream("/data.xml"));
        //3、XPath路径搜索

        System.out.println("===========方式1===========");
        //所有id属性
        List<Node> nodes = document.selectNodes("//@id");
        for (Node node:nodes) {
            Attribute element = (Attribute) node;
            System.out.println(element.getValue());
        }

        System.out.println("===========方式2===========");
        //name标签中中包含id属性的元素
        List<Node> nodes1 = document.selectNodes("//contact[@id]");
        for (Node node:nodes1) {
            Element element = (Element) node;
            System.out.println(element.getName());
        }

        System.out.println("===========方式3===========");
        //name标签中中包含id属性值为1的元素
        List<Node> nodes2 = document.selectNodes("//contact[@id=1]");
        for (Node node:nodes2) {
            Element element = (Element) node;
            System.out.println(element.getName());
        }
    }
}

/*打印输出*/
===========方式1===========
1
2
3
===========方式2===========
contact
contact
contact
===========方式3===========
contact

三、设计模式
(一)工厂模式

1、概念: 一种由内部创建对象的模式,对外提供获取对象的方法。

2、作用:

  • 工厂方法可以封装对象的创建细节,例如对象初始化
  • 可以实现类与类之间的解耦操作(核心思想)——就是不让类直接关联起来。

3、实现:

public class FactoryDemo {
    public static void main(String[] args) {
        Computer c1 = FactoryPattern.getComputer("mac");
        Computer c2 = FactoryPattern.getComputer("huawei");
        c1.run();
        c2.run();
    }
}

class Computer{
    protected String name;
    protected double price;

    public Computer(){}

    public Computer(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public void run(){
        System.out.println(this.name + "正在启动。。。");
    };

    @Override
    public String toString() {
        return "Computer{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

class Mac extends Computer{

    public Mac() {
    }

    public Mac(String mac, double price) {
        this.name = mac;
        this.price = price;
    }
}

class HuaWei extends Computer{
    public HuaWei() {
    }

    public HuaWei(String name, double price) {
        super(name, price);
    }
}

class FactoryPattern{
    public static Computer getComputer(String info){
        switch (info){
            case "mac":
                return new Mac("Mac",9999);
            case "huawei":
                return new HuaWei("HuaWei",5999);
            default:
                return null;
        }
    }
}

/*打印输出*/
Mac正在启动。。。
HuaWei正在启动。。。

(二)装饰模式

1、概念: 创建一个新类,包装原始类,增强原始类的功能。

2、作用:

  • 不改变原类的基础上,动态扩展类的方法。——实际上是一个带有原始类的工具类。
  • 可以实现类与类之间的解耦操作(核心思想)——就是不让类直接关联起来。

3、实现:

public class DecaratorDemo {
    public static void main(String[] args) {
        InputStream inputStream = new FileInputStream();
        System.out.println(inputStream.read());
        byte[] bytes = new byte[100];
        System.out.println(inputStream.read(bytes));
        System.out.println(Arrays.toString(bytes));
    }
}

abstract class InputStream{
    public abstract int read();
    public abstract int read(byte[] buffer);
}

class FileInputStream extends InputStream{

    @Override
    public int read() {
        System.out.println("读取了一个字节a");
        return 97;
    }

    @Override
    public int read(byte[] buffer) {
        for (int i = 0; i < 26; i++) {
            buffer[i] = (byte) (97 + i);
        }
        System.out.println("读取了一个字节数组");
        return 26;
    }
}

/*打印输出*/
读取了一个字节a
97
读取了一个字节数组
26
[97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/625187.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day50|动态规划11-买卖股票的最佳实际3-4(限制买卖次数的情况)

123.买卖股票的最佳时机III 确定递归函数&#xff0c;当前的每一个状态都由前一天决定。 以dp[i][1]和dp[i][2]为例讲解递归函数的含义&#xff1a; dp[i][1]max(dp[i-1][1],dp[i-1][0]-prices[i]) 含义&#xff1a; 第i天的股票第一天持有状态有两种&#xff0c;一种是前一…

电脑msvcr100.dll丢失的解决方法(一键修复方法)

msvcr100.dll是Microsoft Visual C运行时库的组成部分之一&#xff0c;它是一个重要的动态链接库&#xff08;DLL&#xff09;文件&#xff0c;可在Windows操作系统上运行。它包含了许多C/C语言程序库函数的实现&#xff0c;常常被用于支持和调用不同软件程序的运算&#xff0c…

POSTGRES、MYSQL插入数据的UPDATE_INSERT实践

POSTGRES: 1、创建表 create table tbl_user( id serial PRIMARY KEY, name varchar(256), addr varchar(256), age int, score int, fav varchar(256) ); 2、创建唯一约束 alter table tbl_user add constraint name_add_age_unique unique(name,addr,age); 3、首先插入两条数…

Ansible自定义静态资产以及常用模块

静态资产 文件文件&#xff0c;一个格式类似于INI的文件 默认情况下&#xff0c;Ansible的资产文件位于/etc/ansible/host&#xff0c;如果使用pip安装的则可能没有这文件&#xff0c;可以自己创建。 1、自定义资产 #自定义编写inventory.ini文件 1.1.1.1 2.2.2.2 3.3.3.[1:15]…

【C++】—— 模板介绍

前言&#xff1a; 在之前的学习中&#xff0c;我们已经对几个常见的STL库容器进行了详细的讲解&#xff0c;并且进行了模拟实现帮助大家立即。接下来&#xff0c;我们要介绍的就是关于 “模板” 的基本知识。 目录 前言 &#xff08;一&#xff09;非类型模板参数 1、基本介…

Splashtop 推出首款专门面向创作者和创意工作室的高性能远程软件

2023年5月3日 加利福尼亚州库比蒂诺 Splashtop 在简化随处办公的远程解决方案领域处于领先地位&#xff0c;公司今天宣布推出 Splashtop Business Access Performance&#xff0c;这是一款全新的远程访问解决方案&#xff0c;针对独立艺术家、游戏玩家、建筑与设计以及创意公司…

Opencv项目实战:基于dlib的疲劳检测

文章目录 一、项目简介二、算法原理三、环境配置3.1、dlib人脸检测器&#xff1a;dlib.get_frontal_face_detector()3.2、dlib关键点定位工具&#xff1a;shape_predictor_68_face_landmarks.dat 四、项目实战&#xff08;加载视频&#xff09;五、项目实战&#xff08;摄像头获…

软件测试猿和bug的爱恨情仇

对程序猿来说改bug可以位列开发过程中最讨厌的事之首了&#xff0c;这么讲应该没有人会反对吧&#xff1f;因为就连Java之父詹姆斯高斯林也很讨厌Bug。 另一方面对于测试猿来说工作职责就是尽可能多地找出bug&#xff0c;并确保其得以解决。所以被程序猿视为眼中钉肉中刺的bug可…

Doris半结构化数据分析(倒排索引使用)快速入门

1. 背景 Apache Doris2.0 基于Apache Doris向量化MPP引擎&#xff0c;增加了倒排索引和半结构化JSON数据支持&#xff0c;更好地满足日志存储、检索、分析需求。与基于ES的日志存储方案相比&#xff0c;有如下优势&#xff1a; 性价比提升&#xff1a;存储成本降低50%以上&am…

‍☠️stm32Cubemx欠采样原理讲解与实现 采集高频信号

&#x1f3f4;‍☠️STM32Cubemx ADCTIMDMA欠采样采集高频信号 本文主要讲解ADC借助欠采样采集高频信号&#xff0c;比如使用100k左右的采样率去采集1M的信号。 所需工具&#xff1a; 开发板:STM32F103RCT6STM32CubeMXIDE: Keil-MDK 相关文章&#xff1a; STM32HAL ADCTIM…

2核4G轻量服务器阿里云和腾讯云区别对比

阿里云轻量应用服务器2核4G4M带宽297.98元12个月&#xff0c;腾讯云轻量2核4G5M服务器168元一年&#xff0c;628元3年&#xff0c;2核4G轻量应用服务器阿里云和腾讯云怎么选择&#xff1f;哪个性能比较好&#xff1f;阿腾云分享轻量应用服务器2核4G配置阿里云和腾讯云CPU、带宽…

打破互联网思维,我们该如何思考?

在会议上&#xff0c;你是否流程规范讲到一半突然卡逻辑、测分会议疯狂输出周围却一脸问号&#xff1f;提交缺陷时&#xff0c;你又是否被告知看不懂&#xff0c;要求补充信息&#xff1f;受挫时捶胸顿足“表达可太太太重要了&#xff0c;难道我天生脑子转的就比别人慢&#xf…

基于深度学习的高精度红外行人车辆检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度红外行人车辆检测识别系统可用于日常生活中或野外来检测与定位红外行人车辆目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的红外行人车辆目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系…

围绕中国旅行商问题完成综合性实验报告 旅行商问题

题目&#xff1a;围绕中国旅行商问题完成综合性实验报告 旅行商问题&#xff08;TSP问题&#xff09;。 假设有一个旅行商人要拜访全国31个省会城市&#xff0c;它需要选择所要走的路径&#xff0c;路径的限制是每个城市只能拜访一次&#xff0c;而且最后要回到原来出发的城市。…

【裸机驱动LED】使用C代码驱动LED(三)—— C代码编写篇

前面只使用了汇编代码来驱动LED&#xff0c;但是对于后续一些比较复杂的逻辑&#xff0c;使用汇编代码编写驱动的难度太大&#xff0c;因此&#xff0c;这次我们要使用C语言代码来驱动LED。 除了C代码外&#xff0c;依然需要编写汇编代码&#xff0c;在没有OS的情况下&#xf…

基于黄金莱维引导机制的阿基米德优化算法(MSAOA)-附代码

基于黄金莱维引导机制的阿基米德优化算法(MSAOA) 文章目录 基于黄金莱维引导机制的阿基米德优化算法(MSAOA)1.阿基米德优化算法2. 改进阿基米德优化算法2.1 变区间初始化策略2.2 黄金莱维引导机制2.3 自适应波长算子 3.实验结果4.参考文献5.Matlab代码6.Python代码 摘要&#x…

什么是接口测试?怎么做接口测试?Apifox 教你做!

目录 前言&#xff1a; 一、什么是接口测试&#xff1f; 二、接口测试的步骤 三、接口测试工具的选择 四、总结 前言&#xff1a; 随着互联网和移动互联网的发展&#xff0c;企业面对着越来越庞大和复杂的系统和数据接口。在这种情况下&#xff0c;手动测试不再能够满足测…

修复uproject右键菜单完全解决方案办法

在你电脑中找到UnrealVersionSelector通常和epiclauncher是同一个根目录 epiclauncher路径是:D:\MyEpic\Epic Games\Launcher\Portal\Binaries\Win32\EpicGamesLauncher.exe UnrealVersionSelector.exe的路径是:D:\\MyEpic\\Epic Games\\Launcher\\Engine\\Binaries\\Win64\\Un…

探索新科技:3DVR电子楼书引领视觉体验革命

导语&#xff1a; 近年来&#xff0c;科技的迅猛发展引领着我们进入一个全新的数字化时代。在这个时代&#xff0c;虚拟现实和电子书成为了许多领域的热门话题。 接下来&#xff0c;让我们一起探索一个引人注目的技术创新&#xff0c;将虚拟现实和电子书完美结合的3DVR电子楼书…

python基本语法知识(二)

杂项 如果一个制表符/t不能对齐&#xff0c;可以多加几个&#xff1b; 只有将字典转换为字符串的时候才会保留字典的value&#xff0c;转成集合、列表、元组、都会丢失value 函数 例子1&#xff1a; str1 "hello world" # 函数定义 def my_len(data):count 0f…