这辈子没办法做太多事情所以每一件都要做到精彩绝伦
People can't do too many things in my life,so everything will be wonderful
本文档参考资料w3cschool.CHM API教程文档免费下载地址http://down.51cto.com/data/2300287
XML技术
1. 什么是XML
XML 指可扩展标记语言EXtensibleMarkup Language
XML 是一种标记语言很类似 HTML
XML 的设计宗旨是传输数据而非显示数据
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准
html和xml的区别
html超文本标记语言。它主要是用来封装页面上要显示的数据最后通过浏览器来解析html文件然后把数据展示在浏览器上。同样我们可以使用JS和DOM技术对html文件进行解析和操作。
xml可扩展的标记语言。它早期是为了代替html技术但是由于html书写的网页在全球占有率太高最后没有成功。
后期我们开始使用xml文件作为软件的配置文件或者数据的存储文件以及传输数据的文件。
2. XML作用
存储和传输复杂的关系模型数据
在软件系统中作为配置文件使用主要用途
为提高系统的灵活性它所启动的模块通常由其配置文件决定
例如一个软件在启动时它需要启动、两个模块而A、这两个模块在启动时又分别需要A1、A2和B1、B2模块的支持为了准确描述这种关系此时使用文件最为合适不过。
3. XML语法
一个XML文件分为如下几部分内容
文档声明
元素
属性
注释
CDATA区 、特殊字符
处理指令processing instruction
3.1 文档声明
l 在编写XML文档时需要先使用文档声明声明XML文档的类型。也就是告诉其他解析软件该文档是个XML文档。
l 最简单的声明语法
l 用encoding属性说明文档的字符编码经常使用的
l 用standalone属性说明文档是否独立
拖入浏览器解析
注意如果使用记事本编辑的话会解析错误中文乱码问题。只是使用记事本编辑的时候会出现其原因如下
l 常见错误
1. 属性没加引号
2. “1.0” ?> 全角空格
3.编码错误
3.2 元素element
XML元素指XML文件中出现的标签一个标签分为开始标签和结束标签一个标签有如下几种书写形式例如
一个标签中也可以嵌套若干子标签。但所有标签必须合理的嵌套绝对不允许交叉嵌套例如
welcometo wyait.blog.51cto.com/
格式良好的XML文档必须有且仅有一个根标签其它标签都是这个根标签的子孙标签。
对于XML标签中出现的所有空格和换行XML解析程序都会当作标签内容进行处理。例如下面两段内容的意义是不一样的。
第一段
<网址> wyait.blog.51cto.com网址>
第二段
<网址>
wyait.blog.51cto.com
网址>
由于在XML中空格和换行都作为原始内容被处理所以在编写XML文件时使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要被迫改变。
命名规范
一个XML元素可以包含字母、数字以及其它一些可见字符但必须遵守下面的一些规范
区分大小写例如
和
是两个不同的标记。
不能以数字开头
不能包含空格
名称中间不能包含冒号: --- Schema约束冲突
不建议"_"(下划线)开头
属性
一个标签可以有多个属性每个属性都有它自己的名称和取值例如
属性值一定要用双引号"或单引号'引起来
定义属性必须遵循与标签相同的命名规范
在XML技术中标签属性所代表的信息也可以被改成用子元素的形式来描述例如
3.4 注释
Xml文件中的注释采用“”格式。
注意
XML声明之前不能有注释
注释不能嵌套例如
……
-->
3.5 CDATA区
在编写XML文件时有些内容可能不想让解析引擎解析执行而是当作原始内容处理。
遇到此种情况可以把这些内容放在CDATA区里对于CDATA区域内的内容XML解析程序不会处理而是直接原封不动的输出。
语法内容 ]]>
]]>
<demo>
在html表示的是标题标签
在html表示换行
]]>
<h1>在html表示的是标题标签
demo>
3.5.1 转义字符
l 对于一些单个字符若想显示其原始样式也可以使用转义的形式予以处理。
常见的XML转义字符记录如下:
空格:
换行:
缩进:
应当注意,由于系统定义的基本的缩进的格数不同,有的代表4个半角字符,有的代表8个半角字符, 所以可能显示时效果不同。
如果在xml配置中使用了换行、空格、缩进等,解析的时候会把换行、空格、缩进解析为\n、 空格、\t等转义字符!如下:
解析的时候:
代码中会导致,本身配置的放行路径,结果没有放行!
3.6 处理指令processing instruction
处理指令简称PI processinginstruction。处理指令用来指挥解析引擎如何解析XML文档内容。
例如在XML文档中可以使用xml-stylesheet指令通知XML解析引擎应用css文件显示xml文档内容。
处理指令必须以“”作为开头以“?>”作为结尾XML声明语句就是最常见的一种处理指令。
3.7 总结
l 所有XML 元素都须有关闭标签
l XML 标签对大小写敏感
l XML 必须正确地嵌套顺序
l XML 文档必须有根元素(只有一个)
l XML 的属性值须加引号
l 特殊字符必须转义--- CDATA
l XML 中的空格、回车换行会解析时被保留
4. XML约束
什么是XML约束
在XML技术里可以编写一个文档来约束一个XML文档的书写规范这称之为XML约束。
为什么需要XML约束
常用的约束技术
XML DTD
XML Schema XSD
4.1 DTD约束
DTD的快速入门
1、先创建一个xml文件
2、书写一个DTD文件
dtd文件的扩展名必须是dtd
在xml中有多少个标签在dtd中就书写多少个ELEMNT
3、在xml文件中导入DTD的约束
4.1.1 DTD约束语法
DTD和xml文件的结合方式
使用内部DTD
可以把dtd和xml书写在同一个文件中
根标签名 [
写dtd的约束
] >
XML文件使用 DOCTYPE 声明语句来指明它所遵循的DTD文件DOCTYPE声明语句有两种形式
当引用的文件在本地时外部DTD采用如下方式
文档根结点 SYSTEM "DTD文件的URL">
例如 。在xml文件中手写一下。
l 当引用的文件是一个公共的文件时公共DTD采用如下方式
文档根结点 PUBLIC "DTD名称" "DTD文件的URL">
例如
"-//SunMicrosystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
4.1.2 DTD的元素ELEMENT定义
在DTD中使用 ELEMENT 声明当前xml中可以出现的标签名称 () 限制当前这个标签中的文本或者子标签。
告诉我们 当前的xml中可以有一个 books 标签在这个books标签下可以有一个或多个book子标签。
+ 当前括号中的这个标签可以出现一次或多次
当前括号中的这个标签可以出现零次或一次
* 当前括号中的这个标签可以出现零次或多次
括号中的逗号是在定义出现的子标签的顺序。
当前这个name标签中可以书写文本
4.1.3 属性ATTLIST定义
标签名
属性名 属性类型 属性约束
属性名 属性类型 属性约束
...
>
当前book标签上有一个abc属性这个属性的值是一个文本但是这个必须是必须书写的不能省略。
4.1.4 实体ENTITY定义
相关标签参考
4.2 Schema约束XSD约束
4.2.1 Schema概述
XML Schema是用一套预先规定的XML元素和属性创建的这些元素和属性定义了XML文档的结构和内容模式。 XML Schema规定XML文档实例的结构和每个元素/属性的数据类型
Schema相对于DTD的明显好处是XMLSchema文档本身也是XML文档而不是像DTD一样使用自成一体的语法
Schema和DTD区别
XML从SGML中继承了DTD并用它来定义内容的模型验证和组织元素。同时它也有很多局限
DTD不遵守XML语法
DTD不可扩展
DTD不支持命名空间的应用
DTD没有提供强大的数据类型支持只能表示很简单的数据类型。
Schema完全克服了这些弱点使得基于Web的应用系统交换XML数据更为容易。下面是它所展现的一些新特性
Schema完全基于XML语法不需要再学习特殊的语法
Schema能用处理XML文档的工具处理而不需要特殊的工具
Schema大大扩充了数据类型支持booleans、numbers、dates and times、URIs、integers、decimal numbers和real numbers等
Schema支持原型也就是元素的继承。如我们定义了一个“联系人”数据类型然后可以根据它产生“朋友联系人”和“客户联系”两种数据类型
Schema支持属性组。我们一般声明一些公共属性然后可以应用于所有的元素属性组允许把元素、属性关系放于外部定义、组合
开放性。原来的DTD只能有一个DTD应用于一个XML文档现在可以有多个Schema运用于一个XML文档。
4.2.2 Schema基本概念
XML Schema 文件自身就是一个XML文件但它的扩展名通常为.xsd
和XML文件一样一个XMLSchema文档也必须有一个根结点但这个根结点的名称为Schema
应用schema约束 开发xml 过程
W3C预先定义元素和属性-àSchema文档模式文档约束文档-àXML文档实例文档
编写了一个XMLSchema约束文档后通常需要把这个文件中声明的元素绑定到一个地址上这个URI地址叫namespace名称空间以后XML文件就可以通过这个URI即名称空间引用绑定指定名称空间的元素
XML Schema文档基本结构
在W3C XML schema规范中规定所有的Schema文档都使用
4.2.3 Schema快速入门
1、定义一个xml文件
2、书写一个Schema文件
在Schema文件中 必须以 schema作为 Schema文件的根标签。
xmlns="http://www.w3.org/2001/XMLSchema"
它的含义是表示当前的Schema文件是被当前指定的url名称空间所约束。
targetNamespace="http://www.example.org/books"
给当前这个Schema文件起名字当需要被当前这个Schema文件约束的xml文件需要通过当前这个名字引入当前Schema文件。
targetNamespace属性对应的属性值可以是任意的内容。比如targetNamespace="http://www.huyouta.com/books"
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.huyouta.com/books"
elementFormDefault="qualified">
<elementname="books">
<complexType>
<sequence>
<element name="book">
<complexType>
<sequence>
<elementname="name" type="string">element>
<elementname="author"type="string">element>
<elementname="price"type="double">element>
sequence>
complexType>
element>
sequence>
complexType>
element>
schema>
3、在xml文件中引入Schema文件
xmlns="http://www.huyouta.com/books"
在xml中引入 Schema文件的名称
xml version="1.0" encoding="UTF-8"?>
<books xmlns="http://www.huyouta.com/books"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.huyouta.com/booksbooks.xsd"
>
<book>
<name>葵花宝典name>
<author>班长author>
<price>9.9price>
book>
books>
4.2.4 名称空间
声明文档空间
targetNamespace="http://www.huyouta.com/books "
elementFormDefault="qualified"
attributeFormDefault="unqualified"
>
targetNamespace元素用于指定schema文档中声明的元素属于哪个名称空间。
elementFormDefault元素用于指定局部元素是否受到该schema指定targetNamespace所指定的名称空间限定
attributeFormDefault元素用于指定局部属性是否受到该schema指定targetNamespace所指定的名称空间限定
总结
在书写Schema文件的时候需要在Schema文件中 使用 targetNamespace 属性 给当前的Schema文件起名。
把targetNamespace属性的值做为当前 Schema文件的名称空间。
在xml文件中 需要 通过 xmlns 来引入不同名称下的Schema文件。
如果我们在同一个 xml文件中引入了多个Schema的名称空间这时需要大家给这些名称空间其别名。
如果在xml文件使用了多个 xmlns引入多个名称空间时需要在xmlns后面使用冒号给当前的名称空间起名。通过这个别区分到底当前xml中的标签受限于具体哪个Schema文件。
5. XML解析
DOM-Document Object Model-文档对像模型。是w3c组织处理xml的一种方式。
特点
一次将所有数据全部加载到内存中。
对xml文档中的每一个节点都当成一个Node对像处理。包括元素、文本、属性。
org.w3c.dom包中的Document,Element,Node。
非常方便进行修改。
已经集成在了JDK中是Sun对xml操作的标准。
缺点是当文档数据量很大时对内存的占用很大。
Sax – Sample Api for XML 。
在读取数据时分析数据通过事件监听器来完成。
速度快但只适合读取数据仅向前读取不可后退。
xml可扩展的标记语言。
不管是html文件还是xml文件它们都是标记型文档都可以使用w3c组织制定的dom技术来解析。
dom解析技术是W3C组织制定的而所有的编程语言都对这个解析技术使用了自己语言的特点进行实现。
Java对dom技术解析标记型文档也做了实现
早期sun公司就制定的 dom 技术。而这个技术在页面xml的时候需要把整个xml文件加载到内存中可以根据getElementById、getElementsByName 、getElementsByTagName 等方法解析。
sun公司在JDK6版本对 dom解析技术进行升级 SAX解析 Stax 解析
sun公司的解析统称 JAXP。
5.1 解析XML的方式
JAXP(JavaApi for Xml Programming) – sun公司的一套操作XML的API.
DOM解析-一次性的将数据全部装入内存。
SAX解析-边读取边解析。
Dom4j(Document For Java)-第三方开源是从jdom分裂出来的解析技术。目前jdom已经完全被dom4j替代。
jDom – Dom4j的前身。
Dom4j在性能和速度上都比sun公司的要快而且支持Xpath快速查找目前像Spring,Hibernate这些大型的框架都是用的dom4j.
StAX – JDK1.6新特性做为JAXP的新成员已经集成在了JDK6当中。
Dom4j
Dom4j是一个开源、灵活的XML API。
目前很多开源框架如struts,hibernate都使用dom4j做为解析其xml的工具。
支持文档的读写功能和Xpath快速查询操作。
由于dom4j 它不是sun公司的技术而属于第三方公司的技术我们需要使用dom4j 就需要到dom4j官网下载dom4j的jar包。
把dom4jjar包拷贝我们的项目中
在自己的项目中新建一个lib文件把dom4j jar包拷贝到其中
把jar包添加到当前的classpath路径中
5.2.1 获取document对象
//注意以下类都来自于org.dom4j包
//1、实例化解析器
SAXReader sax = newSAXReader();
//2、读取xml文档
Document doc =sax.read("./src/xml/a.xml");
//3、必须先获取根节点
Element root =doc.getRootElement();
//4、获取第一个人的姓名
String name =root.element("user").element("name").getText();
System.err.println(name);
5.2.2 获取所有标签中的文本值
//演示使用dom4j 获取 xml中的标签中的数据
publicstaticvoid getElement()throws Exception{
SAXReader reader = new SAXReader();
// 获取dom树
Document dom = reader.read("users.xml");
//获取xml中的根标签
Element root = dom.getRootElement();
//获取根标签下的所有子标签
List
//遍历集合获取到每个 user标签
for (Element e : list) {
Elementname = e.element("name");
Elementage = e.element("age");
Elementsex = e.element("sex");
System.out.println(name.getText() + ":" + age.getText()+":"+ sex.getText());
}
}
5.2.3 修改指定标签中的值
//把最后一个user中的sex 修改为女
publicstaticvoid UpdateElement()throws Exception{
SAXReader reader = new SAXReader();
// 获取dom树
Document dom = reader.read("users.xml");
//先获取根标签
Element root = dom.getRootElement();
//获取 users 下的所有user标签
List
//获取最后一个user标签
Element lastUser =list.get(list.size()-1);
Element sex = lastUser.element("sex");
sex.setText("女");
//把内存中修改后的dom树重新写到xml文件中
//创建用于写出数据的流对象
//XMLWriter writer = new XMLWriter(newFileOutputStream("users.xml"));
//创建一个格式器
OutputFormat format = OutputFormat.createPrettyPrint();
//设置编码表
format.setEncoding("gbk");
XMLWriter writer = new XMLWriter(new FileWriter("users.xml") ,format );
//写出数据
writer.write(dom);
//关流
writer.close();
}
5.2.4 删除标签
// 删除
publicstaticvoid deleteElement() throws Exception {
SAXReader reader = new SAXReader();
// 获取dom树
Document dom = reader.read("users.xml");
// 删除最后一个user标签
// 先获取根标签
Element root = dom.getRootElement();
// 获取 users 下的所有user标签
List
// 获取最后一个user标签
Element lastUser = list.get(list.size() -1);
root.remove(lastUser);
XMLWriter writer = new XMLWriter(newFileOutputStream("users.xml"));
writer.write(dom);
// 关流
writer.close();
}
5.2.5 增加标签
// 创建一个新的dom写到文件
publicstaticvoid addElement() throws Exception {
// 先创建一个dom树这个dom树在内存中
Document dom = DocumentHelper.createDocument();
// 给树上添加根节点
Element books = dom.addElement("books");
// 给根books上添加了2个book 标签
Element book = books.addElement("book");
Element book2 = books.addElement("book");
// 给book标签上添加子标签
Element name = book.addElement("name");
Element author = book.addElement("author");
Element price = book.addElement("price");
// 给book下的子标签中添加文本
name.setText("九阴真经");
author.addText("李白");
price.addText("1.1");
// 给book标签上添加子标签
Element name2 = book2.addElement("name");
Element author2 = book2.addElement("author");
Element price2 = book2.addElement("price");
// 给book下的子标签中添加文本
name2.setText("九阳神功");
author2.addText("赵敏");
price2.addText("1.2");
// 给book标签上添加属性
book.addAttribute("addr", "藏经阁");
book2.addAttribute("addr", "桃花岛");
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(newFileOutputStream("books2.xml"),format);
writer.write(dom);
// 关流
writer.close();
}
5.2.6 工具类抽取
/**
* 这时一个工具类它的功能是完成对dom数的获取和保存
*
* @authorwyait
* @version 1.0
*/
publicclass DomUtils {
privatestatic Document dom = null;
static{
try{
SAXReaderreader = new SAXReader();
// 获取dom树
dom = reader.read("users.xml");
}catch( Exception e ){
//把异常写到日志文件中
System.out.println("恭喜您获取dom树失败");
}
}
/**
* 用于获取dom树的方法
*/
publicstatic DocumentgetDom(){
returndom;
}
/**
* 保存dom树
*/
publicstaticvoid saveDom(){
try{
OutputFormatformat = OutputFormat.createPrettyPrint();
XMLWriterwriter = new XMLWriter(new FileOutputStream("users.xml"),format);
writer.write(dom);
// 关流
writer.close();
}catch(Exception e){
System.out.println("恭喜您保存dom树失败");
}
}
}
5.2.7 Dom4j生成一个新的XML文件
//1、通过DocumentHelper在内存中创建一个Document
Document doc = DocumentHelper.createDocument();
doc.setXMLEncoding(“UTF-8”);//XML的编码格式
//生成一个节点,生成的第一个节点也是根节点此方法只使用一次
Element root =doc.addElement(“users”);
root.addElement(“user”).setText(“Jack”);//再设置一个子节点同时设值
//写出,如果有中文请使用前一页所讲的技术处理
XMLWriter writer= new XMLWriter(new FileOutputStream(“a.xml”));
Writer.write(doc);
Writer.close();
5.3 xpath技术偏理论
xpath技术 也是 W3C 组织制定的 快速获取 xml 文件中某个 标签的 技术。
l XML PATH Language。
l 可以实现快速查询。
l XPATH包含
XPath 使用路径表达式在XML 文档中进行导航。
XPath 包含一个标准函数库
l 准备Xpath的包
jaxen.jar
l Xpath通过以下方法使用
dom.selectNodes – 返回一个List对像
dom.selectSingleNode – 返回一个Node对像
5.3.1 Xpath示例
//以下选择所有的user节点,处理不带命名空间的安以下原则
List
System.err.println(list.size());
//以下选择所有name节点
list = doc.selectNodes("//name");//或从要开始:/users//name
System.err.println(list.size());
//以下选择所在带有country属性的节点
list = doc.selectNodes("//user[@country]");
System.err.println(list.size());
//选择国家是 EN的节点,可以使用以下方法查询用户登录
//如果country不能重复则可以使用selectSingleNode
//使用双引号或单引号都可以//user
Node node =doc.selectSingleNode("//user[@country=\"EN\"]");
System.err.println(node);
在xpath中 / 表示从根开始找标签 // 表示 不考虑标签的位置 只要匹配上就可以
//abc[@属性名] 选择abc标签但是要求abc 必须有指定属性名
在使用xpath技术结合 dom4j 快速获取标签 发生了异常
报了类没有找到异常。这时一般情况下都是缺少jar包。
一般如果缺少jar包的话 在报的异常中的第二个单词或者第三个单词是jar包的名称。
不区分大小写的解决方案
以下均为根据属性查询
//以下查询id元素为XX且name属性为用户组的name值的建立全部转成小写
String path = "//user[fn:upper-case(@id)=‘XX"'and fn:upper-case(@name)='"+name+"']";
Node n=dom.selectSingleNode(path);//因为确定有一个对象所以使用Single
或是转成小写以下查询id属性为hello的book元素
List list =dom.selectNodes("//book[fn:lower-case(@id)='hello']");
Xpath模糊查询属性
查询属性中包含某个值的元素类似于like
//book[contains(@id,’A001’)]
//查询book的id属性中包含A001字符串的
既然是模糊查询当然要进行一下大小写转换所以
//book[contains(fn:lower-case(@id),’a001’)]
Xpath通过查询子元素的值区别主要元素:不要使用@符号
如XML文档如下
查询包含Oracle一词的所有book元素。
//book[name=‘Oracle’] //精确查询子元素name的值为Oracle的book元素
//以下是模糊查询
//book[contains(name,’Oracle’)]
//也可以将name元素的值转成小写
//book[contains(fn:lower-case(name),’oracle’]
Xpath处理带有命名空间的XML文档
由于命名空间的namespace是组成元素的一部分即前缀所以处理带有命名空间的XML文档时必须要设置命名空间
如
对于上面的文档所有的元素都来自于默认命名空间。
Xpath处理带有命名空间的XML文档
SAXReader sax = new SAXReader();
//声明一个map用于保存命名空间
Map
//给命名空间取一个别名
uris.put("a","http://www.itcast.cn");
//设置命名空间后再读取xml文档
sax.getDocumentFactory().setXPathNamespaceURIs(uris);
Document dom =sax.read("./xml2/a.xml");
//然后使用带有命名空间的前缀查询即可。
dom.selectNodes(“//a:book”);
//带有属性的查询同前
dom.selectNodes(//a:book[@id]
//带有元素的查询必须要添加命名空间的前缀
dom.seletNodes(“//a:book[a:name=‘oralce’]”); //查询子元素值为oracle的book元素
6. 总结
l SAXStAX读取速度快。都是JAXP的成员。
l StAXIterator编程接口和Cursor编程接口。
l Dom4j。Dom。都会将所有节点加载加载到内存中。CRUD非常方便。
l Dom4j支持XPath.