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

news/2024/10/22 12:31:25/

一、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(属性名)获取属性值
    @Testpublic 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>

实现代码

    @Testpublic 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 {@Testpublic 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 {@Testpublic 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 {@Testpublic 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 {@Testpublic 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 + "正在启动。。。");};@Overridepublic 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{@Overridepublic int read() {System.out.println("读取了一个字节a");return 97;}@Overridepublic 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.ppmy.cn/news/283564.html

相关文章

Day_47选择排序

目录 一. 选择排序的实现 1. 简单选择排序 2. 性能分析 二. 代码实现 1. 核心代码 三. 代码展示 四. 数据测试 五. 总结 一. 选择排序的实现 1. 简单选择排序 选择排序的基本思想是&#xff1a;每一趟&#xff08;如第i趟&#xff09;在后面n-i1&#xff08;i1,2,3...n-1&a…

GLaDOS加速网络套餐edu教育网邮箱免费使用

产品介绍 教育优惠分享的好处&#xff0c;就是能一对一接触到网友的真实需求和最新的教育优惠产品&#xff0c;今天的这款也是网友投稿分享。 GLaDOS用于教育&#xff1a;建立开放思想和开放社会 GLaDOS Education可帮助学生&#xff0c;教师和学校找到他们掌握网络所需的工具…

用vi或vim编辑文件时出现e325: attention错误的解决办法

原因是编辑文档时出现错误操作&#xff0c;自动创建的临时文件&#xff0c;删除即可&#xff01;&#xff01;&#xff01; 解决方法一&#xff1a; 在出现“e325: attention”错误的提示时&#xff0c;按 “D” 即刻删除临时文件。 解决方法二&#xff1a; 进入需要编辑的…

error: command ‘D:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\cl.exe‘ f

跟着知乎“略略略”大佬改建YOLOv5的旋转目标检测项目。 在python项目中使用C文件&#xff0c;首先安装了swig&#xff0c;将polyiou.i文件编译生成了polyiou.cpp文件&#xff0c;然后执行 python setup.py build_ext --inplace 结果报了一大堆polyiou.cpp中的错误&#xff0c;…

#174-D: expression has no effect报错解决方法

今天进行编程时&#xff0c;代码写完&#xff0c;进行编译时突然弹出以上错误&#xff0c;在网上找了好久的答案都是所答非所问&#xff0c;思考好久找到了错误&#xff0c;这也是新手编程最容易犯的错误。造成此错误的原因就是在调用函数时后面忘加了( )&#xff0c;在我的程序…

vi编辑时出现E325:ATTENTION(简单易懂,快速解决问题)

当出现这个问题时&#xff0c;是因为由于在编辑该文件的时候异常退出了&#xff0c;因为vim在编辑文件时会创建一个交换文件swap file以保证文件的安全性。要想解决这个问题&#xff0c; 1.找到开头前两行 示例如下&#xff1a; E325: ATTENTION Found a swap file by the n…

nyoj325 zb的生日 DFS

#include<stdio.h> #include<math.h> int a[21],sum,all,n,i,j,min; void dfs(int star) { if(starn) return; if(fabs(all-sum*2)<min)//差值更小 minfabs(all-sum*2); for(int jstar;j<n;j) { suma[j]; dfs(j1); sum-a[j]; } } int main() { while(sca…

SAP MM之移动类型(Movement type-MVT)

SAP如何在系统中实现对物流的控制&#xff1a; 一、需要满足的最基本需求是&#xff1a;物流的进、出、消耗&#xff1a; 1、何来何往&#xff1a;来&#xff08;采购订单/生产订单/其它库位&#xff09;&#xff1b;往&#xff08;销售订单/生产订单/成本中心/内部订单/其它库…