Java SE基础知识详解第[20]期—XML、XML解析、设计模式

简介: Java SE基础知识详解第[20]期—XML、XML解析、设计模式

XML、XML解析、设计模式

1.XML

1.1XML概述

XML概述

XML是可扩展标记语言(eXtensible Markup Language)的缩写,它是是一种数据表示格式,可以用于自定义数据格式,描述非常复杂的数据结构,常用于传输和存储数据。

XML示例如下图所示。

XML_Example.png

XML的几个特点和使用场景

①纯文本,默认使用UTF-8编码,可嵌套;

②如果把XML内容存为文件,那么它就是一个XML文件;

③XML的使用场景:XML内容经常被当成消息进行网络传输,或者作为配置文件用于存储系统的配置信息

1.2XML的创建、语法规则

XML的创建

就是创建一个XML类型的文件,要求文件的后缀必须使用xml,如hello_world.xml

XML的语法规则

XML文件的后缀名为:xml

文档声明必须是第一行

如<?xmversion="1.0" encoding="UTF-8" ?>

version:XML默认的版本号码、该属性是必须存在的。

encoding:本XML文件的编码。

XML的标签(元素)规则

标签由一对尖括号和合法标识符组成:<name></name>,必须存在一个根标签,有且只能有一个

标签必须成对出现,有开始,有结束:<name></name>

特殊的标签可以不成对,但是必须有结束标记,如:<br/>

标签中可以定义属性,属性和标签名空格隔开,属性值必须用双引号引起来<student id = “1”></name>

标签需要正确的嵌套

XML的其他组成

XML文件中可以定义注释信息:<!– 注释内容 -->

XML文件中某些需要替代的特殊字符

字符

替代值

含义

<

<

小于

>

>

大于

&

&

'

'

单引号

"

"

双引号

 

XML文件中可以存在CDATA区<![CDATA[ …内容… ]]>,里面的内容可以随意填写,无需使用字符替代某些特殊字符,IDEA中的快捷键CD

1.3XML文档约束方式

什么是文档约束?

由于XML文件可以自定义标签,导致XML文件可以随意定义,程序在解析的时候可能出现问题。文档约束是用来限定xml文件中的标签以及属性应该怎么写,以此强制约束程序员必须按照文档约束的规定来编写xml文件

文档约束的分类:DTD、schema

使用文档约束的步骤

①:编写schema约束文档,后缀必须是.xsd(编写DTD约束文档,后缀必须是.dtd),具体的形式到代码中观看。

②:在需要编写的XML文件中导入该schema(DTD)约束文档

③:按照约束内容编写XML文件的标签。

注:文档约束-DTD可以约束XML文件的编写,不能约束具体的数据类型schema本身也是一个xml文件,本身也受到其他约束文件的要求,所以编写的更加严谨,可以约束具体的数据类型,约束能力上更强大。

2.XML解析技术

2.1XML解析技术概述

XML的数据的作用是什么,最终需要怎么处理?

存储数据、做配置信息、进行数据传输,最终需要被程序进行读取,解析里面的信息。

什么是XML解析

使用程序读取XML中的数据

两种解析方式:SAX解析、DOM解析

DOM解析解析文档对象模型图示如下图所示。

DOM.png

其中,整个xml文档称为Document对象;Element对象代表标签(图示蓝色区域);Attribute对象代表属性(图示紫色区域);Text对象代表文本内容(图示黄色区域),且后三者均实现了Node接口。

Dom解析常用框架:Dom4j:把文件一次性加载到内存中,加载为Document对象再操作。

2.2Dom4J解析XML文件

Dom4J的解析思想?

得到文档对象Document,从中获取元素对象和内容。

导入Dom4J框架步骤

① 下载Dom4j框架,官网下载。 ② 在项目中创建一个文件夹:lib ③ 将dom4j-2.1.1.jar文件复制到 lib 文件夹④ 在jar文件上点右键,选择 Add as Library -> 点击OK ⑤ 在类中导包使用

Dom4j解析XML-得到Document对象

SAXReader类构造器

方法名

说明

public SAXReader()

创建Dom4J的解析器对象

 

SAXReader类得到Document的方法

方法名

说明

Document read(String url)

加载XML文件成为Document对象

 

Document得到根元素的方法

方法名

说明

Element getRootElement()

获得根元素对象

 

各级元素的方法

方法名

说明

List<Element> elements()

得到当前元素下所有下一级子元素

List<Element> elements(String name)

得到当前元素下指定名字的子元素返回集合

Element element(String name)

得到当前元素下指定名字的子元素

如果有很多名字相同的返回第一个

String getName()

得到元素名字

String attributeValue(String name)

通过属性名如果有直接得到属性值

String elementText(子元素名)

得到指定名称的子元素

此子元素只有文本,不含有子元素的文本

String getText()

得到此元素只有文本,不含有子元素文本

 

示例代码如下:

publicclassDom4JHelloWorld {
@TestpublicvoidparseXMLData() throwsException {
// 1.创建一个Dom4j的解析器对象,代表整个dom4j框架SAXReadersaxReader=newSAXReader();
// 2.把XML文件加载到内存中称为一个Document文档对象//        Document document = saxReader.read(new File("day15_xml_app\\src\\Contacts.xml"));// 此种通过File对象寻找的方式的缺点:需要通过模块名寻找,一旦模块名被修改,会找不到// getResourceAsStream中的"/"是直接去src下寻找文件InputStreamis=Dom4JHelloWorld.class.getResourceAsStream("/Contacts.xml");
// 通过此种方式找到文件字节输入流,再传递给read方法,即使模块名修改,不影响找到该xml文件Documentdocument=saxReader.read(is);
// 获取根元素Elementroot=document.getRootElement();
System.out.println(root.getName()); // contactList    }
}

注:getResourceAsStream中的"/"是直接去src下寻找文件不受模块改名的影响。如InputStream is = Dom4JHelloWorld.class.getResourceAsStream("/Contacts.xml");

XML解析案例

需求:利用Dom4J的知识,将Contact.xml文件中的联系人数据封装成List集合,其中每个元素是实体类Contact。打印输出 List 中的每个元素。

示例代码如下:

Contact.xml

<?xmversion="1.0" encoding="UTF-8"?><contactList><contactid="1"vip="true"><name>   潘金莲  </name><gender></gender><email>panpan@itcast.cn</email></contact><contactid="2"vip="false"><name>武松</name><gender></gender><email>wusong@itcast.cn</email></contact><contactid="3"vip="false"><name>武大狼</name><gender></gender><email>wuda@itcast.cn</email></contact><user></user></contactList>

Contact类

publicclassContact {
privateintid;
privatebooleanvip;
privateStringname;
privatecharsex;
privateStringemail;
publicContact() {
    }
publicContact(intid, booleanvip, Stringname, charsex, Stringemail) {
this.id=id;
this.vip=vip;
this.name=name;
this.sex=sex;
this.emai=email;
    }
publicintgetId() {
returnid;
    }
publicvoidsetId(intid) {
this.id=id;
    }
publicbooleanisVip() {
returnvip;
    }
publicvoidsetVip(booleanvip) {
this.vip=vip;
    }
publicStringgetName() {
returnname;
    }
publicvoidsetName(Stringname) {
this.name=name;
    }
publicchargetSex() {
returnsex;
    }
publicvoidsetSex(charsex) {
this.sex=sex;
    }
publicStringgetEmail() {
returnemail;
    }
publicvoidsetEmail(Stringemail) {
this.emai=email;
    }
@OverridepublicStringtoString() {
return"Contact{"+"id="+id+", vip="+vip+", name='"+name+'\''+", sex="+sex+", email='"+emai+'\''+'}';
    }
}

测试类

publicclassDom4JTest2 {
@TestpublicvoidparseToList() throwsException {
// 1.导入Dom4J框架// 2.创建SAXReader对象SAXReadersaxReader=newSAXReader();
// 3.加载XML文件称为Document对象Documentdocument=saxReader.read(Dom4JTest2.class.getResourceAsStream("/Contacts.xml"));
// 4.获取根元素Elementroot=document.getRootElement();
// 5.提取contact子元素List<Element>contactEles=root.elements("contact");
// 6.准备ArrayList集合封装联系人信息List<Contact>contactList=newArrayList<>();
// 7.遍历contact子元素for (ElementcontactEle : contactEles) {
// xml文件中的值都是文本,需要使用包装类进行类型转换// 此处不能用强转,需要使用类型转换,强转必须保证被强转的变量类型就是强转后的类型才可以intcontactId=Integer.valueOf(contactEle.attributeValue("id"));
booleancontactIsVip=Boolean.valueOf(contactEle.attributeValue("vip"));
StringcontactName=contactEle.elementTextTrim("name");
charcontactSex=contactEle.elementTextTrim("gender").charAt(0);
StringcontactEmai=contactEle.elementTextTrim("email");
// 8.每一个子元素都是一个联系人对象// 9.把联系人对象加入到contactList集合中contactList.add(newContact(contactId, contactIsVip,
contactName, contactSex, contactEmail));
        }
// 10.遍历contactList集合for (Contactcontact : contactList) {
System.out.println(contact);
        }
    }
}

程序运行结果如下:

Contact{id=1, vip=true, name='潘金莲', sex=女, email='panpan@itcast.cn'}

Contact{id=2, vip=false, name='武松', sex=男, email='wusong@itcast.cn'}

Contact{id=3, vip=false, name='武大狼', sex=男, email='wuda@itcast.cn'}

注:xml文件中的值都是文本,需要进行类型转换不能用强转强转必须保证被强转的变量类型就是强转后的类型向下转型才可以类型转换是不同类型之间的变量的相互转换

Dom4J的解析后的数据形式通常数据会封装成Java的对象,如单个对象,或者集合对象形式

一键修改所有出现该变量的变量名:Shift + F6。

3.XML检索技术:Xpath

如果需要从XML文件中检索需要的某个信息(如name)怎么解决?

Dom4j需要进行文件的全部解析,然后再寻找数据。

Xpath技术更加适合做信息检索。

XPath介绍

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

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

使用Xpath检索出XML文件

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

分析:

① 导入jar包(dom4j和jaxen-1.1.2.jar),Xpath技术依赖Dom4j技术

② 通过dom4j的SAXReader获取Document对象

③ 利用XPath提供的API,结合XPath的语法完成选取XML文档元素节点进行解析操作。

Document中与Xpath相关的API

方法名

说明

Node selectSingleNode("表达式")

获取符合表达式的唯一元素

List<Node> selectNodes("表达式")

获取符合表达式的元素集合

 

Xpath的四大检索方案:绝对路径、相对路径、全文检索、属性查找

XPath:绝对路径:采用绝对路径获取从根节点开始逐层的查找/contactList/contact/name节点列表并打印信息:/根元素/子元素/孙元素,从根元素开始,一级一级向下查找,不能跨级。

XPath:相对路径:采用相对路径获取当前元素下一级contact 节点的name子节点并打印信息:./子元素/孙元素,从当前元素开始,一级一级向下查找,不能跨级。

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

//contact:找contact元素,无论元素在哪里。

//contact/name:找name,无论在哪一级,但name一定是contact的子节点。

//contact//name:contact无论在哪一种,name只要是contact的子孙元素都可以找到。

XPath:属性查找:在全文中搜索属性,或者带属性的元素。

//@属性名:查找属性对象,无论是哪个元素,只要有这个属性即可。

//元素[@属性名]:全文搜索查找含有此属性的元素对象。

//元素//[@属性名=‘值’]:全文搜索查找含有此属性且属性值值为的元素对象。

4.设计模式:工厂模式

什么是工厂设计模式?

之前我们创建类对象时,都是使用new对象的形式创建,在很多业务场景下也提供了不直接new的方式。

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种获取对象的方式。

工厂设计模式的作用:

工厂的方法可以封装对象的创建细节,比如:为该对象进行加工和数据注入。

可以实现类与类之间的解耦操作,只需要在FactoryPattern中维护,其他使用到的地方一并修改(核心思想)。

示例代码如下:

电脑类

publicabstractclassComputer {
privateStringname;
privatedoubleprice;
publicComputer() {
    }
abstractvoidstart();
publicStringgetName() {
returnname;
    }
publicvoidsetName(Stringname) {
this.name=name;
    }
publicdoublegetPrice() {
returnprice;
    }
publicvoidsetPrice(doubleprice) {
this.price=price;
    }
}

苹果电脑类

publicclassMacextendsComputer{
@Overridevoidstart() {
System.out.println(this.getName() +"苹果电脑启动了");
    }
}

华为电脑类

publicclassHuaweiextendsComputer{
@Overridevoidstart() {
System.out.println(this.getName() +"华为电脑启动了");
    }
}

工厂类

publicclassFactoryPattern {
/*定义一个方法,创建对象并返回*/publicstaticComputercreatComputer(Stringinfo) {
switch (info) {
case"华为":
Computerc=newHuawei();
c.setName("Huawei pro 16");
c.setPrice(5999);
returnc;
case"苹果":
Computerc2=newMac();
c2.setName("Mac pro 2");
c2.setPrice(11999);
returnc2;
default:
returnnull;
        }
    }
}

工厂模式测试类

publicclassFactoryDemo {
publicstaticvoidmain(String[] args) {
Computerc1=FactoryPattern.creatComputer("华为");
c1.start(); // Huawei pro 16华为电脑启动了Computerc2=FactoryPattern.creatComputer("苹果");
c2.start(); // Mac pro 2苹果电脑启动了    }
}

5.设计模式:装饰模式

什么是装饰设计模式?

创建一个新类,包装原始类,从而在新类中提升原来类的功能。

装饰设计模式的作用:

作用:装饰模式指的是在不改变原类的基础上,动态地扩展一个类的功能

装饰模式示例如下图所示。

DeclarationPattern.png

装饰模式具体步骤如下:

定义父类。

② 定义原始类,继承父类,定义功能。

③ 定义装饰类,继承父类,包装原始类在原始类的基础上进行方法改进,增强功能

示例代码如下:

接口类(共同父类)

publicabstractclassInputStream {
publicabstractintread();
publicabstractintread(byte[] buffer);
}

原始类

publicclassFileInputStreamextendsInputStream {
@Overridepublicintread() {
System.out.println("以低性能的方式读取了一个字节a");
return97;
    }
@Overridepublicintread(byte[] buffer) {
buffer[0] =97;
buffer[1] =98;
buffer[2] =99;
System.out.println("以低性能的方式读取了一个字节数组"+Arrays.toString(buffer));
return3;
    }
}

装饰类

publicclassBufferedInputStreamextendsInputStream {
privateInputStreamis;
publicBufferedInputStream(InputStreamis) {
this.is=is;
    }
@Overridepublicintread() {
System.out.println("提供8kb的缓冲区,提高读取性能");
returnthis.is.read();
    }
@Overridepublicintread(byte[] buffer) {
System.out.println("提供8kb的缓冲区,提高读取性能");
returnthis.is.read(buffer);
    }
}

测试类

publicclassDecoratorPattern {
publicstaticvoidmain(String[] args) {
InputStreamis=newBufferedInputStream(newFileInputStream());
System.out.println(is.read());
System.out.println(is.read(newbyte[3]));
    }
}

程序运行结果如下:

提供8kb的缓冲区,提高读取性能

以低性能的方式读取了一个字节a

97

提供8kb的缓冲区,提高读取性能

以低性能的方式读取了一个字节数组[97, 98, 99]

3

相关文章
|
4天前
|
存储 安全 算法
【常见集合】Java 常见集合重点解析
【常见集合】Java 常见集合重点解析
8 0
|
1天前
|
XML 数据格式
XML Schema 复杂元素类型详解:定义及示例解析
在XML Schema(XSD)中,复杂元素包含其他元素和/或属性,分为4类:空元素、仅含元素、仅含文本和既含元素也含文本。定义复杂元素可通过直接声明或引用预定义的复杂类型。复杂空元素仅含属性,而仅含元素的类型则只包含其他子元素。XSD提供了`&lt;xs:sequence&gt;`、`&lt;xs:all&gt;`、`&lt;xs:choice&gt;`等指示器来规定元素顺序和出现次数,以及`&lt;xs:attributeGroup&gt;`和`&lt;xs:group&gt;`来组织元素和属性。
23 7
|
2天前
|
XML Web App开发 JavaScript
XML DOM 解析器
浏览器内置的XML解析器将XML转换为JavaScript可操作的DOM对象。通过XMLHttpRequest加载XML文档,如`books.xml`,创建HTTP请求并获取响应,然后将响应解析为XML DOM,以便用JavaScript访问和处理。示例代码展示了在不同浏览器中如何使用XMLHttpRequest加载XML。
|
3天前
|
缓存 算法 Java
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
|
3天前
|
XML Web App开发 JavaScript
XML DOM 解析器
XML解析器将XML转换为JavaScript可操作的DOM对象,使得浏览器(大多内置此解析器)能读取和处理XML。通过XMLHttpRequest对象,可以加载XML文档,如示例所示,创建HTTP请求获取&quot;books.xml&quot;,然后将响应转化为DOM对象以进行访问和操作。
|
4天前
|
设计模式 Java 数据库连接
【企业场景】设计模式重点解析(下)
【企业场景】设计模式重点解析
6 0
|
4天前
|
设计模式 算法 Java
【企业场景】设计模式重点解析(上)
【企业场景】设计模式重点解析
9 0
|
4天前
|
XML Web App开发 JavaScript
XML DOM 解析器
浏览器内置XML解析器,用于读取和操作XML。它将XML转化为XML DOM,允许JavaScript访问、修改节点。以下JS代码示例加载&quot;books.xml&quot;到DOM对象:检查浏览器支持,创建XMLHttpRequest或ActiveXObject,打开GET请求,发送并获取响应,将响应转换为XML DOM。
|
4天前
|
Java 开发工具 Maven
java解析apk获取应用信息
请注意,你需要替换"path/to/your/apkfile.apk"为你的APK文件的实际路径。
11 0
|
4天前
|
设计模式 安全 网络协议
【设计模式】代理模式例子解析
【设计模式】代理模式例子解析
10 2

推荐镜像

更多