这辈子没办法做太多事情所以每一件都要做到精彩绝伦
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 是 W3C 的推荐标准
html和xml的区别
html超文本标记语言。它主要是用来封装页面上要显示的数据最后通过浏览器来解析html文件然后把数据展示在浏览器上。同样我们可以使用JS和DOM技术对html文件进行解析和操作。
xml可扩展的标记语言。它早期是为了代替html技术但是由于html书写的网页在全球占有率太高最后没有成功。
后期我们开始使用xml文件作为软件的配置文件或者数据的存储文件以及传输数据的文件。
2.XML作用
存储和传输复杂的关系模型数据
在软件系统中作为配置文件使用主要用途
为提高系统的灵活性它所启动的模块通常由其配置文件决定
例如一个软件在启动时它需要启动、两个模块而A、这两个模块在启动时又分别需要A1、A2和B1、B2模块的支持为了准确描述这种关系此时使用文件最为合适不过。
3.XML语法
文档声明
元素
注释
CDATA区 、特殊字符
处理指令processing instruction
3.1文档声明
l 在编写XML文档时需要先使用文档声明声明XML文档的类型。也就是告诉其他解析软件该文档是个XML文档。
l 最简单的声明语法
<?xmlversion="1.0" ?>
l 用encoding属性说明文档的字符编码经常使用的
<?xmlversion="1.0" encoding="UTF-8" ?>
l 用standalone属性说明文档是否独立
<?xmlversion="1.0" encoding=" UTF-8" standalone="yes" ?>
拖入浏览器解析
注意如果使用记事本编辑的话会解析错误中文乱码问题。只是使用记事本编辑的时候会出现其原因如下
l 常见错误
1. <?xml version=1.0 ?> 属性没加引号
2. <?xml version=“1.0” ?> 全角空格
3.编码错误
3.2元素element
包含标签体<a>wyait.blog.51cto.com/</a>
不含标签体的<a></a>,简写为<a/>
<a>welcometo <b> wyait.blog.51cto.com/</a></b>
第一段
<网址> wyait.blog.51cto.com</网址>
第二段
<网址>
wyait.blog.51cto.com
</网址>
由于在XML中空格和换行都作为原始内容被处理所以在编写XML文件时使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要被迫改变。
命名规范
一个XML元素可以包含字母、数字以及其它一些可见字符但必须遵守下面的一些规范
<inputtype=“text”>
<input><type>text</type></input>
3.4注释
Xml文件中的注释采用“<!--注释-->”格式。
注意
XML声明之前不能有注释
注释不能嵌套例如
<!--大段注释
……
<!--局部注释-->
……
-->
3.5CDATA区
语法<![CDATA[ 内容 ]]>
<![CDATA[
<wyait>
<br/>
</wyait >
]]>
<demo>
<!--
当我们希望把一些文本原样的显示在浏览器中时
可以使用xml中提供的cdata区域
格式
<![CDATA[需要原样显示的数据]]>
由于CDATA区域书写麻烦可以使用特殊字符
< <
> >
-->
<![CDATA[
<br>在html表示换行
]]>
</demo>
3.5.1转义字符
l对于一些单个字符若想显示其原始样式也可以使用转义的形式予以处理。
常见的XML转义字符记录如下:
空格:<string name="out_bound_submit">出  库</string> 其中的 就代表空格!解析的时候,空格还是空格!
换行: <string name="hello_world">你好!\n世界!</string> 其中的\n就代表换行
缩进: <string name="hello_world">你好!\t世界!</string> 其中的\t就代表按一次Tab键的几个空格
应当注意,由于系统定义的基本的缩进的格数不同,有的代表4个半角字符,有的代表8个半角字符, 所以可能显示时效果不同。
如果在xml配置中使用了换行、空格、缩进等,解析的时候会把换行、空格、缩进解析为\n、 空格、\t等转义字符!如下:
解析的时候:
代码中会导致,本身配置的放行路径,结果没有放行!
3.6处理指令processing instruction
处理指令简称PI processinginstruction。处理指令用来指挥解析引擎如何解析XML文档内容。
例如在XML文档中可以使用xml-stylesheet指令通知XML解析引擎应用css文件显示xml文档内容。 <?xml-stylesheettype="text/css" href="1.css"?>
处理指令必须以“<?”作为开头以“?>”作为结尾XML声明语句就是最常见的一种处理指令。
3.7总结
lXML 标签对大小写敏感
lXML 必须正确地嵌套顺序
lXML 文档必须有根元素(只有一个)
lXML 的属性值须加引号
l特殊字符必须转义--- CDATA
lXML 中的空格、回车换行会解析时被保留
4.XML约束
什么是XML约束
在XML技术里可以编写一个文档来约束一个XML文档的书写规范这称之为XML约束。
为什么需要XML约束
常用的约束技术
XML DTD
XML Schema XSD
4.1DTD约束
DTD的快速入门
1、先创建一个xml文件
2、书写一个DTD文件
dtd文件的扩展名必须是dtd
在xml中有多少个标签在dtd中就书写多少个ELEMNT
3、在xml文件中导入DTD的约束
4.1.1DTD约束语法
DTD和xml文件的结合方式
使用内部DTD
可以把dtd和xml书写在同一个文件中
<!DOCTYPE 根标签名 [
写dtd的约束
] >
XML文件使用 DOCTYPE 声明语句来指明它所遵循的DTD文件DOCTYPE声明语句有两种形式
当引用的文件在本地时外部DTD采用如下方式
<!DOCTYPE文档根结点 SYSTEM "DTD文件的URL">
例如 <!DOCTYPE books SYSTEM“book.dtd”>。在xml文件中手写一下。
<!DOCTYPE文档根结点 PUBLIC "DTD名称" "DTD文件的URL">
例如<!DOCTYPE web-app PUBLIC
"-//SunMicrosystems,Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
4.1.2DTD的元素ELEMENT定义
在DTD中使用 ELEMENT 声明当前xml中可以出现的标签名称 () 限制当前这个标签中的文本或者子标签。
告诉我们 当前的xml中可以有一个 books 标签在这个books标签下可以有一个或多个book子标签。
+ 当前括号中的这个标签可以出现一次或多次
当前括号中的这个标签可以出现零次或一次
* 当前括号中的这个标签可以出现零次或多次
括号中的逗号是在定义出现的子标签的顺序。
当前这个name标签中可以书写文本
4.1.3属性ATTLIST定义
<!ATTLIST 标签名
...
>
当前book标签上有一个abc属性这个属性的值是一个文本但是这个必须是必须书写的不能省略。
4.1.4实体ENTITY定义
相关标签参考
4.2Schema约束XSD约束
4.2.1Schema概述
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.2Schema基本概念
应用schema约束 开发xml 过程
W3C预先定义元素和属性-àSchema文档模式文档约束文档-àXML文档实例文档
编写了一个XMLSchema约束文档后通常需要把这个文件中声明的元素绑定到一个地址上这个URI地址叫namespace名称空间以后XML文件就可以通过这个URI即名称空间引用绑定指定名称空间的元素
XML Schema文档基本结构
在W3C XML schema规范中规定所有的Schema文档都使用<schema>作为其根元素
<schema>元素可以包含一些属性。一个XMLschema声明看起来经常以如下的形式出现
4.2.3Schema快速入门
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">
<!--
在Schema文件中书写当前xml中可以出现的标签 以及子标签 等信息
1、先清楚xml中需要多少标签在Schema文件中就书写多少个element标签
2、element标签中的 name属性 就是xml中 可以书写的标签的名字
3、在Schema中它把xml中可以出现的标签分成简单标签和复杂标签
复杂标签如果标签上有属性或者有子标签或者有属性和子标签 或 属性和文本的标签复杂标签
4、针对复杂标签需要在当前的标签中书写子标签来限制当前复杂标签中的其他内容
在element标签中需要使用complexType声明当前的element标签name属性指定的是一个复杂标签
如果是简单标签可以使用simpleType
5、对于复杂标签需要在 complexType中书写sequence 标签表示子标签的顺序
-->
<elementname="books"> <!--books 是一个复杂标签 -->
<complexType>
<sequence> <!-- 定义当前books 标签中的子标签的顺序-->
<element name="book">
<complexType> <!-- 声明当前的book 又是一个复杂标签-->
<sequence>
<!-- 在element 标签中的 type属性来限制当前单标签中文本的类型 -->
<elementname="name" type="string"></element>
<elementname="author"type="string"></element>
<elementname="price"type="double"></element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
xmlns="http://www.huyouta.com/books"
<?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.9</price>
</book>
</books>
4.2.4名称空间
声明文档空间
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.huyouta.com/books "
elementFormDefault="qualified"
attributeFormDefault="unqualified"
>
<xs:schema>
targetNamespace元素用于指定schema文档中声明的元素属于哪个名称空间。
elementFormDefault元素用于指定局部元素是否受到该schema指定targetNamespace所指定的名称空间限定
attributeFormDefault元素用于指定局部属性是否受到该schema指定targetNamespace所指定的名称空间限定
总结
在书写Schema文件的时候需要在Schema文件中 使用 targetNamespace 属性 给当前的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 �C 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) �C sun公司的一套操作XML的API.
DOM解析-一次性的将数据全部装入内存。
SAX解析-边读取边解析。
Dom4j(Document For Java)-第三方开源是从jdom分裂出来的解析技术。目前jdom已经完全被dom4j替代。
jDom �C Dom4j的前身。
Dom4j在性能和速度上都比sun公司的要快而且支持Xpath快速查找目前像Spring,Hibernate这些大型的框架都是用的dom4j.
StAX �C JDK1.6新特性做为JAXP的新成员已经集成在了JDK6当中。
Dom4j
Dom4j是一个开源、灵活的XML API。
目前很多开源框架如struts,hibernate都使用dom4j做为解析其xml的工具。
由于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获取所有标签中的文本值
publicstaticvoid getElement()throws Exception{
SAXReader reader = new SAXReader();
// 获取dom树
Document dom = reader.read("users.xml");
Element root = dom.getRootElement();
List<Element> list =root.elements();
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();
List<Element> list =root.elements();
Element lastUser =list.get(list.size()-1);
Element sex = lastUser.element("sex");
sex.setText("女");
//创建用于写出数据的流对象
//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");
Element root = dom.getRootElement();
List<Element> list = root.elements();
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");
Element book = books.addElement("book");
Element book2 = books.addElement("book");
Element name = book.addElement("name");
Element author = book.addElement("author");
Element price = book.addElement("price");
name.setText("九阴真经");
author.addText("李白");
price.addText("1.1");
Element name2 = book2.addElement("name");
Element author2 = book2.addElement("author");
Element price2 = book2.addElement("price");
name2.setText("九阳神功");
author2.addText("赵敏");
price2.addText("1.2");
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工具类抽取
/**
*
* @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树失败");
}
}
/**
*/
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.7Dom4j生成一个新的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.3xpath技术偏理论
xpath技术 也是 W3C 组织制定的 快速获取 xml 文件中某个 标签的 技术。
l XML PATH Language。
l XPATH包含
XPath 使用路径表达式在XML 文档中进行导航。
XPath 包含一个标准函数库
l 准备Xpath的包
jaxen.jar
l Xpath通过以下方法使用
dom.selectNodes �C 返回一个List对像
dom.selectSingleNode �C 返回一个Node对像
5.3.1Xpath示例
//以下选择所有的user节点,处理不带命名空间的安以下原则
List<Element> list =doc.selectNodes("//user");
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());
//如果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
List list =dom.selectNodes("//book[fn:lower-case(@id)='hello']");
//book[contains(@id,’A001’)]
既然是模糊查询当然要进行一下大小写转换所以
//book[contains(fn:lower-case(@id),’a001’)]
Xpath通过查询子元素的值区别主要元素:不要使用@符号
如XML文档如下
<books>
<book id=“A001”>
<name>Oracle编程基础</name>
<price>89.99</price>
</book>
</books>
查询包含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<String,String> uris = newHashMap<String,String>();
//给命名空间取一个别名
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.
原文链接:/xml/294254.html