文章目录
- 动态代理
- 概述
- XML
- Dom4j
-
- XML解析
- 解析方式和解析器
-
- 解析方式
- 解析器
- Snipaste_2024-04-17_21-22-44.png
- [<br />解析器开发包](#
解析器开发包)
- 基本使用
- 使用xpath解析xml文件
动态代理
概述
提供一个代理的对象,有了代理对象后,当访问某个方法时,会被代理对象拦截(拦截后可以对方法进行前增强,后增强)[代理对象不会破坏原有方法的代码]
特点
- 动态的创建.class文件(创建一个和被代理类实现相同父接口的子类[代理类])
- 动态的加载.class文件到内存中(创建Class对象)
- Proxy类需要一个类加载器
- 对程序员来讲,不需要书写代理类
代码实现
java
代理对象 = Proxy.newProxyInstance(累加载器,父接口,处理器);
类加载器:动态的加载.class文件
父接口:代理类和被代理类共同的父接口
处理器:代理对象拦截了方法后,对方法进行前增强,后增强,是由处理器来书写逻辑
代理对象 = Proxy.newProxyInstance(
类.class.getClassLoader(),
被代理类.class.getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
proxy:代理对象
method:被拦截的方法对象
args:被拦截的方法中的实参
return method.invoke("代理对象",args);
}
}
);
实现的关键步骤
- 被代理类:必须有实现接口
- 创建被代理类对象:交给代理对象使用
优点
- 非常的灵活,支持任意接口类型的实现对象做代理,也可以直接为接口本身做代理
- 可以为被代理对象的所有方法做代理
- 可以在不改变方法源码的情况下,实现对方法功能的增强
- 不仅简化了编程工作,提高了软件系统的可扩展性,同时也提高了开发效率
XML
概述
Extensible Markup Language 可扩展的标记语言,由各种(标记,元素)组成
可扩展:所有的标签都是自定义的,可以随意扩展的
标记语言:整个文档由各种标签组成,清晰,数据结构化
作用
- 数据交换:不同计算机之间,不同操作系统之间,不同数据库之间,进行数据交换
- 配置文件 :主要用于各种框架的配置文件
编写第一个XML文件
- 先创建文件
- 编写person.xml文件
java
<?xml version="1.0" encoding="UTF-8" ?>
<peopel>
<person>
<id>1</id>
<name>张三</name>
<age>18</age>
<sex>男</sex>
</person>
<person>
<id>2</id>
<name>李四</name>
<age>20</age>
<sex>女</sex>
</person>
</peopel>
- 通过浏览器解析xml的内容
注 :XML以后通过Java来进行解析,很少直接在浏览器上显示
组成
声明
<?xml version="1.0" encoding="utf-8" ?> 固定格式
文档声明必须为<?xml开头,以?>结束
必须在xml文档中的首行首列
常见的俩个属性:
- version:指定XML文档版本,必须属性,这里选择1.0
- encoding:指定当前文档的编码,可选属性,默认值为utf-8
元素(标签、标记)
格式1 : 标签体 有标签体的标签(双标签)
格式2 : 没有标签体的标签(空标签) (单标签)
元素体 :可以是元素,也可以是文本
元素命名 :和Java命名标识符保持一致
一个XML中有且仅有一个根元素
属性
- 是元素的一部分,必须出现在元素的开始标签中
- 定义格式: 属性名 = "属性值"
- 一个元素可以有0~N个属性,但一个元素中不能同名出现
- 属性名建议以Java的标识符定义规则做参考
注释
<!--注释内容--> ctrl+/
转义字符[实体字符
字符 | 预定义的转义字符 | 说明 |
---|---|---|
< | < | 小于(less than) |
> | > | 大于(greater than) |
" | " | 双引号(quotation) |
' | ' | 单引号(apostrophe) |
& | & | 和号(ampersand ) |
字符区(了解)
当大量的转义字符出现在xml文档中时,会使xml文档的可读性大幅度降低。这时候使用CDATA段会好一些
CDATA(Character Data)字符数据区,格式如下
<![CDATA[
文本数据 < > & ; " "
]]>
特点 :原样显示(书写的内容不会被xml解析器解析)
CD+enter
约束
DTD约束
java
<!ELEMENT 书架 (书+)> <!-- 声明了根元素,并指定了根元素下必须有的一个子元素 -->
<!-- 声明子元素 书 -->
<!ELEMENT 书 (书名,作者,售价)><!--约束元素书的子元素必须为书名、作者、售价-->
<!-- , 表示必须按照元素的顺序出现 -->
<!ELEMENT 书名 (#PCDATA)> <!-- #PCDATA : 表示文本内容 -->
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
引用 <!DOCTYPE 根元素 SYSTEM "dtd约束文件的路径">
java
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE 书架 SYSTEM "bookshelf.dtd"><!--指定使用bookshelf.dtd文件约束当前xml文档-->
<书架>
<书>
<书名>JavaWeb开发教程</书名>
<作者>张孝祥</作者>
<售价>100.00元</售价>
</书>
<书>
<书名>三国演义</书名>
<作者>罗贯中</作者>
<售价>100.00元</售价>
<测试>hello</测试><!--不符合约束,书的子元素必须为书名、作者、售价-->
</书>
</书架>
Schema约束
概念 :Schema语言也叫做XSD(XML Schema Definition)
其本身也是xml格式文档,但Schema文档扩展名为xsd,而不是xml,它功能强大,数据类型约束更完善
java
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn"
elementFormDefault="qualified">
<xs:element name='书架' >
<!-- complexType : 复杂元素
xml文档中的某个标签,有子标签或有属性,该标签就为:复杂元素
例: <书架> <书>
简单元素:
没有子标签、没有属性。 例:书名、作者、售价
-->
<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>
java
<?xml version="1.0" encoding="UTF-8"?>
<书架
xmlns="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn bookshelf.xsd"
><!--指定schema文档约束当前XML文档-->
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>abc</售价>
</书>
</书架>
引入步骤
<根元素 xmlns="命名空间"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="命名空间 文件路径"
</根元素>
命名空间为约束文件中的targetNamespace中
名称空间
一个XML文档最多可以使用一个DTD文件,但一个XML文档中使用多个Schema文件,若这些Schema文件中定义了相同名称的元素时,使用的时候就会出现名字冲突。
同理 , 在XML文档中就需要通过名称空间(namespace)来区分元素和属性是来源于哪个约束中的。
名称空间就在在根元素后面的内容 , 使用xmlns到引入约束 。
当一个XML文档中需要使用多个Schema文件的时候 , 有且仅有一个使用缺省的 , 其他的名称空间都需要起别名 。
xmlns="http://www.itcast.cn"
xmlns:aa="http://java.sun.com"
Dom4j
XML解析
当数据存储在xml中,我们希望通过程序获取xml的内容,使用io的话会比较繁琐,所有后来创造了解析器,方便开发人员操作xml
解析方式和解析器
解析方式
- DOM:将整个xml文件装入内存,并解析成一个Document对象
- SAX:边扫描边分析,只能读
- PULL:Android内置的xml解析方式,类似sax
解析器
就是根据不同的解析方式提供具体实现
解析器开发包
基本使用
DOM解析原理及结构模型
解析原理
将整个xml文档加载到内存中,生成一个DOM树,并获得Document对象,通过Document对象就可以对DOM数进行操作
java
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="0001">
<name>JavaWeb开发教程</name>
<author>张孝祥</author>
<sale>100.00元</sale>
</book>
<book id="0002">
<name>三国演义</name>
<author>罗贯中</author>
<sale>100.00元</sale>
</book>
</books>
结构模型
DOM中的核心概念就是节点,在xml文档中的元素、属性、文本,在DOM中都是节点!所有的节点都封装到了Document对象中
使用Document对象,就可以去访问DOM树中的每个节点
常用的方法
- SAXReader对象
方法 | 作用 |
---|---|
SAXReader sr = new SAXReader(); | 构造器 |
Document read(String url) | 加载执行xml文档 |
- Document对象
方法 | 作用 |
---|---|
Element getRootElement() | 获得根元素 |
- Element对象
方法 | 作用 |
---|---|
List elements(String ele ) | 获得指定名称的所有子元素。可以不指定名称 |
Element element(String ele) | 获得指定名称第一个子元素。 |
String getName() | 获得当前元素的元素名 |
String attributeValue(String attrName) | 获得指定属性名的属性值 |
String elementText(Sting ele) | 获得指定名称子元素的文本值 |
String getText() | 获得当前元素的文本内容 |
使用xpath解析xml文件
介绍
XPath使用路径表达式 来选取XML/HTML 文档中的元素节点或属性节点。节点是通过沿着路径 (path) 来选取的。XPath在解析XML/HTML文档方面提供了一独树一帜的路径思想。
使用步骤
- 导入jar包(dom4j和jaxen-1.1-beta-6.jar)
- 通过dom4j的SaxReader获取Document对象
- 利用Xpath提供的api,结合xpath的语法完成选取XML文档元素节点进行解析操作
Node接口中存在的方法
方法 | 作用 |
---|---|
List<Element> selectNodes("路径表达式") |
获取符合表达式的元素集合 |
Element selectSingleNode("路径表达式") |
获取符合表达式的唯一元素 |
Document,Element都是Node的子类型,也可以使用上述的方法
路径表达式
- 绝对路径表达式
例如: /元素/子元素/子子元素...
- 相对路径表达式
例如: 子元素/子子元素... 或者 ./子元素/子子元素...
- 全文搜索路径表达式
例如: //子元素//子子元素或者//子子元素
- 条件筛选表达式
例如: //元素[@属性名]或者//元素[@属性名=value]