在 web 编程中, 可以通过浏览器访问 Web 服务器上的资源.
Web 服务器就是另一台计算机.
浏览器的入口不同(访问路径), 访问的资源也不同.
为了灵活实现的不同路径执行不同的资源, 需要使用 xml 进行配置;
为了限定 xml 内容, 需要使用 xml 约束(DTD 或 schema);
为了获得 xml 的内容, 需要使用 dom4j 进行解析.
1 xml 概述
xml 称为 Extensible Markup Language, 意思是可扩展的标记语言.
xml 语法上和 html 比较相似, 但 HTML 中的元素是固定的, 而 xml 的标签是可以由用户自定义的.
使用 1.0 版本.
xml 被设计用来传输和存储数据.
2 xml 与 HTML 的差异
xml 不是 HTML 的替代. xml 是对 HTML 的补充.
xml 和 HTML 为不同的目的而设计:
xml 被设计为传输和存储数据, 其焦点是数据的内容.
HTML 被设计用来显示数据, 其焦点是数据的外观.
HTML 旨在显示信息, 而 xml 旨在传输信息.
3.1 文档声明
<?xml version="1.0" encoding="UTF-8"?>
1)文档声明必须为 <?xml 开头, 以?> 结束
2)文档声明必须从文档的 0 行 0 列位置开始(必须在第一行, 注释也不能加)
3)文档声明只有属性:
versioin: 指定 xml 文档版本. 必须属性, 只写 1.0
Encoding: 指定当前文档的编码. 可选属性, 默认值是 utf-8
3.2 元素
1)元素是 xml 文档中最重要的组成部分
2)普通元素的结构由开始标签, 元素体, 结束标签组成. 例如:<hello > 大家好</hello>
3)元素体: 元素体可以是元素, 也可以是文本, 例如:<b><a > 你好</a></b>
4)必须正确地嵌套
5)空元素: 空元素只有开始标签, 没有结束标签, 但元素必须闭合, 例如:<c/>
6)元素命名:
区分大小写
不能使用空格, 不能使用冒号
不建议以 xml, xml, xml 开头
7)格式化良好的 xml 文档, 必须只有一个根元素
3.3 属性
1)属性是元素的一部分, 必须出现在元素的开始标签中
2)属性的定义格式: 属性名 = 属性值, 属性值必须使用单引号或双引号
3)一个元素可以有 0-n 个属性, 但一个元素中不能出现同名属性
4)属性名不能使用空格, 冒号等特殊字符, 且必须以字母开头
3.4 注释
xml 的注释与 HTML 相同, 以 "<!--" 开始, 以 "-->" 结束.
注释内容会被 xml 解析器忽略.
3.5 转义字符(实体引用)
xml 中的转义字符与 HTML 一样.
因为很多符号己经被 xml 文档结构所使用, 所以在元素体或属性值中想使用这些符号就必须使用转义字符, 例如:"<",">","'",""","&".
Tips: 在 XML 中, 只有字符 "<" 和 "&" 确实是非法的. 大于号是合法的, 但是用实体引用来代替它是一个好习惯.
3.6 CDATA 区
当大量的转义字符出现在 xml 文档中时, 会使 xml 文档的可读性大幅度降低. 这时如果使用 CDATA 段就会好一些.
在 CDATA 段中出现的 "<",">',,""","'","&", 都无需使用转义字符. 这可以提高 xml 文档的可读性.
在 CDATA 段中不能包含 "]]>", 即 CDATA 段的结束定界符.
例:
建一个 xml 文件:
- <?xml version="1.0" encoding="UTF-8"?>
- <school name="oracle" size="3">
- <persons>
- <person>
- <name > 张三</name>
- <age>18</age>
- </person>
- <person>
- <name > 李四 & lt;</name>
- <![CDATA[
- if(a>"3"){
- a=2;
- }
- ]]>
- <age>19</age>
- </person>
- </persons>
- </school>
预览:
右键 --Open With--Other--
4 约束
常用 DTD 约束和 Schema 约束
5 DTD
DTD (Document Type Definition ), 文档类型定义, 用来约束 xml 文档.
规定 xml 文档中元素的名称, 子元素的名称及顺序, 元素的属性等.
开发中, 很少自己编写 DTD 约束文档, 通常都是通过框架提供的 DTD 约束文档, 编写对应的 xml 文档.
常见框架使用 DTD 约束有: struts2,hibernate 等.
5.1DTD 语法
5.1.1 文档声明(第 2 和第 3 种常用)
1)内部 DTD, 在 xml 文档内部嵌入 DTD, 只对当前 xml 有效.
<?xml version="1.0" encoding="UTF-8"? standalone="yes" ?> <!DOCTYPE web-app [ ...// 具体语法 ]> <web-app> </web-app> |
2)外部 DTD-- 本地 DTD,DTD 文档在本地系统上, 公司内部自己项目使用.
3)外部 DTD-- 公共 DTD,DTD 文档在网络上, 一般都有框架提供.
5.1.2 元素声明
符号 | 符号类型
| 描述 | 示例
|
? | 问号 | 表示该对象可以出现,但只能出现一次 | (菜鸟?)
|
* | 星号
| 表示该对象允许出现任意多次,也可以是零次 | (爱好 *)
|
+ | 加号
| 表示该对象最少出现一次,可以出现多次 | (成员 +)
|
() | 括号
| 用来给元素分组 | (古龙 | 金庸 | 梁羽生), (王朔 | 余杰), 毛毛
|
| | 竖条
| 表明在列出的对象中选择一个
| (男人 | 女人)
|
, | 逗号 | 表示对象必须按指定的顺序出现 | (西瓜, 苹果, 香蕉)
|
实例:
<!ELEMENT web-app(servlet*,servlet-mapping*,welcome-file-list?)> web-app 包括 3 个标签,且必须顺序出现。 servlet 子标签个数任意 servlet-mapping 子标签个数任意 welcome-file-list 子标签最多只能出现一次 <!ELEMENT servlet(servlet-name,description?,(servlet-class|jsp-file))> servlet 有 3 个子标签,且必须顺序出现 servlet-name,必须有,且只能出现 1 次 description,可选 1 次 servlet-class 和 jsp-file 二选一,且只能出现一次 <!ELEMENT servlet-name(#PCDATA)> servlet-name 的标签体必须是文本 <!ELEMENT welcome-file-list (welcome-file+)> welcome-file-list 至少有 1 个子标签 welcome-file
|
5.1.3 属性声明
语法了解一下即可.
5.2 实际使用
1)
把这个 dtd 文件复制项目中的包中
在同级目录下建一个 Web.xml(注意, 一个项目只能有一个 Web.xml 文件)
2)复制这一句到 Web.xml 中:
3)然后 Alt+/ 就有提示了
实例代码:
<?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE Web-App SYSTEM "web-app_2_3.dtd">
- <Web-App>
- <servlet>
- <servlet-name>hello</servlet-name>
- <servlet-class>demo01.Hello</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>hello</servlet-name>
- <url-pattern>/hello</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- <welcome-file>index.HTML</welcome-file>
- </welcome-file-list>
- </Web-App>
简单解释(以后会再学):
浏览器访问地址: http://localhost/zyx/hello
后面的 / hello 就是 servlet-mapping 中的 url-pattern, 所以这里要加个 /, 根据这个找到
servlet-name, 再找到 servlet 中的 servlet-name, 再找到 servlet-class, 里面的包名 + 类名, 就找到要执行的类了, 这就是程序的入口.
welcome-file-list 是欢迎页面, 当只访问项目时, 先显示第一个 welcome-file 里的页面, 如果没有, 再接着找第二个页面.
6 Schema 约束(常用)
Schema 是新的 xml 文档约束
Schema 要比 DTD 强大很多, 是 DTD 替代者
Schema 本身也是 xml 文档, 但 Schema 文档的扩展名为 xsd, 而不是 xml
Schema 功能更强大, 数据类型更完善
Schema 支持名称空间
6.1 实际使用
和 dtd 大体一样, 也是先把. xsd 加到项目中, 再建 Web.xml 文件
复制声明, 再 Alt+/, 一一点出来即可
实例代码:
- <?xml version="1.0" encoding="UTF-8"?>
- <Web-App xmlns="http://www.example.org/web-app_2_5"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
- version="2.5">
- <servlet>
- <servlet-name>AddServlet</servlet-name>
- <servlet-class>demo01.AddServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>AddServlet</servlet-name>
- <url-pattern>/AddServlet</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- <welcome-file>index.HTML</welcome-file>
- </welcome-file-list>
- </Web-App>
7 dom4j 解析
当将数据存储在 xml 后, 我们就希望通过程序获得 xml 的内容.
IO 流可以, 但太繁琐
7.1 解析方式
1)DOM
解析器把整个 xml 文档装载到内存, 并解析成一个 Document 对象.
优点: 元素与元素之间保留结构关系, 故可以进行增删改查操作.
缺点: xml 文档过大, 可能出现内存溢出现象.
2)SAX
是一种速度更快, 更有效的方法. 它逐行扫描文档, 一边扫描一边解析. 并以事件驱动的方式进行具体解析, 每执行一行, 都将触发对应的事件.
优点: 处理速度快, 可以处理大文件
缺点: 只能读, 逐行后将释放资源.
3)PULL
Android 内置的 xml 解析方式, 类似 SAX.
7.2 常见的解析开发包
JAXP:sun 公司提供支持 DOM 和 SAX 开发包
JDom:dom4j 兄弟
Jsoup: 一种处理 HTML 特定解析开发包
dom4j: 比较常用的解析开发包, hibernate 底层采用
7.3DOM 解析原理及结构模型
xml DOM 和 HTML DOM 类似, xml DOM 将整个 xml 文档加载到内存, 生成一个 DOM 树,
并获得一个 Document 对象, 通过 Document 对象就可以对 DOM 进行操作.
DOM 中的核心概念就是节点, 在 xml 文档中的元素, 属性, 文本等, 在 DOM 中都是节点.
7.4 API 使用
常用方法:
1)导入 jar 包
2)步骤:
1. 获取解析器
2. 获得 document 文档对象
3. 获取根元素
4. 获取根元素下的子元素
5. 遍历子元素
6. 判断元素名称为 servlet 的元素
7. 获取 servlet-name 元素
8. 获取 servlet-class 元素
例 1:
- <?xml version="1.0" encoding="UTF-8"?>
- <Web-App xmlns="http://www.example.org/web-app_2_5"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
- version="2.5">
- <servlet>
- <servlet-name>AddServlet</servlet-name>
- <servlet-class>demo01.AddServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>AddServlet</servlet-name>
- <url-pattern>/AddServlet</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- <welcome-file>index.HTML</welcome-file>
- </welcome-file-list>
- </Web-App>
- import java.util.List;
- import org.dom4j.Document;
- import org.dom4j.DocumentException;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
- public class Demo01 {
- public static void main(String[] args) throws DocumentException {
- //1. 获取解析器
- SAXReader saxReader=new SAXReader();
- //2. 获得 document 文档对象
- Document doc=saxReader.read("src/demo02/web.xml");
- //3. 获取根元素
- Element root=doc.getRootElement();
- //4. 获取根元素下的子元素
- List<Element> elements=root.elements();
- //5. 遍历子元素
- for(Element e:elements){
- //6. 判断元素名称为 servlet 的元素
- if(e.getName().equals("servlet")){
- //7. 获取 servlet-name 元素
- Element servletName=e.element("servlet-name");
- //8. 获取 servlet-class 元素
- Element servletClass=e.element("servlet-class");
- System.out.println(servletName.getText());
- System.out.println(servletClass.getText());
- }
- }
- }
- }
例 2: 通过反射模拟获取对象并调用方法
- <?xml version="1.0" encoding="UTF-8"?>
- <Web-App xmlns="http://www.example.org/web-app_2_5"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
- version="2.5">
- <servlet>
- <servlet-name>AddServlet</servlet-name>
- <servlet-class>demo03.AddServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>AddServlet</servlet-name>
- <url-pattern>/AddServlet</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- <welcome-file>index.HTML</welcome-file>
- </welcome-file-list>
- </Web-App>
- public class AddServlet {
- public void init(){
- System.out.println("servlet 初始化");
- }
- public void service(){
- System.out.println("servlet 业务");
- }
- public void destroy(){
- System.out.println("servlet 销毁");
- }
- }
- import org.dom4j.Document;
- import org.dom4j.DocumentException;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
- public class Test {
- public static void main(String[] args) throws DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException {
- //1. 创建解析器对象
- SAXReader saxReader=new SAXReader();
- //2. 使用解析器加载 Web.xml 文件得到 document 对象
- Document doc=saxReader.read("src/demo03/web.xml");
- //3. 获取根元素节点
- Element root=doc.getRootElement();
- //4. 根据元素名称获取子元素节点
- Element servlet=root.element("servlet");
- //5. 根据元素名称获取 servlet-class 的文本节点
- Element servletClass=servlet.element("servlet-class");
- String classTest=servletClass.getText();
- //6. 通过类全名获取字节码文件
- Class c=Class.forName(classTest);
- //7. 创建实例对象
- Object obj=c.newInstance();
- AddServlet add=(AddServlet)obj;
- //8. 调用实例对象里面的方法
- add.init();
- add.service();
- add.destroy();
- }
- }
xml
来源: http://www.bubuko.com/infodetail-2909743.html