这辈子没办法做太多事情所以每一件都要做到精彩绝伦
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 指可扩展标记语言EXtensibleMarkup Language
XML 是一种标记语言很类似 HTML
XML 的设计宗旨是传输数据而非显示数据
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准
html和xml的区别
html超文本标记语言。它主要是用来封装页面上要显示的数据最后通过浏览器来解析html文件然后把数据展示在浏览器上。同样我们可以使用JS和DOM技术对html文件进行解析和操作。
xml可扩展的标记语言。它早期是为了代替html技术但是由于html书写的网页在全球占有率太高最后没有成功。
后期我们开始使用xml文件作为软件的配置文件或者数据的存储文件以及传输数据的文件。
存储和传输复杂的关系模型数据
在软件系统中作为配置文件使用主要用途
为提高系统的灵活性它所启动的模块通常由其配置文件决定
例如一个软件在启动时它需要启动、两个模块而A、这两个模块在启动时又分别需要A1、A2和B1、B2模块的支持为了准确描述这种关系此时使用文件最为合适不过。
一个XML文件分为如下几部分内容
文档声明
元素
属性
注释
CDATA区 、特殊字符
处理指令processing instruction
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.编码错误
XML元素指XML文件中出现的标签一个标签分为开始标签和结束标签一个标签有如下几种书写形式例如
包含标签体<a>wyait.blog.51cto.com/</a>
不含标签体的<a></a>,简写为<a/>
一个标签中也可以嵌套若干子标签。但所有标签必须合理的嵌套绝对不允许交叉嵌套例如
<a>welcometo <b> wyait.blog.51cto.com/</a></b>
格式良好的XML文档必须有且仅有一个根标签其它标签都是这个根标签的子孙标签。
对于XML标签中出现的所有空格和换行XML解析程序都会当作标签内容进行处理。例如下面两段内容的意义是不一样的。
第一段
<网址> wyait.blog.51cto.com</网址>
第二段
<网址>
wyait.blog.51cto.com
</网址>
由于在XML中空格和换行都作为原始内容被处理所以在编写XML文件时使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要被迫改变。
命名规范
一个XML元素可以包含字母、数字以及其它一些可见字符但必须遵守下面的一些规范
区分大小写例如<P>和<p>是两个不同的标记。
不能以数字开头
不能包含空格
名称中间不能包含冒号: --- Schema约束冲突
不建议"_"(下划线)开头
一个标签可以有多个属性每个属性都有它自己的名称和取值例如
<inputtype=“text”>
属性值一定要用双引号"或单引号‘引起来
定义属性必须遵循与标签相同的命名规范
在XML技术中标签属性所代表的信息也可以被改成用子元素的形式来描述例如
<input><type>text</type></input>
Xml文件中的注释采用“<!--注释-->”格式。
注意
XML声明之前不能有注释
注释不能嵌套例如
<!--大段注释
……
<!--局部注释-->
……
-->
在编写XML文件时有些内容可能不想让解析引擎解析执行而是当作原始内容处理。
遇到此种情况可以把这些内容放在CDATA区里对于CDATA区域内的内容XML解析程序不会处理而是直接原封不动的输出。
语法<![CDATA[ 内容 ]]>
<![CDATA[
<wyait>
<br/>
</wyait >
]]>
<demo>
<!--
当我们希望把一些文本原样的显示在浏览器中时
可以使用xml中提供的cdata区域
格式
<![CDATA[需要原样显示的数据]]>
由于CDATA区域书写麻烦可以使用特殊字符
< <
> >
-->
<![CDATA[
<h1>在html表示的是标题标签
<br>在html表示换行
]]>
<h1>在html表示的是标题标签
</demo>
l 对于一些单个字符若想显示其原始样式也可以使用转义的形式予以处理。
处理指令简称PI processinginstruction。处理指令用来指挥解析引擎如何解析XML文档内容。
例如在XML文档中可以使用xml-stylesheet指令通知XML解析引擎应用css文件显示xml文档内容。 <?xml-stylesheettype="text/css" href="1.css"?>
处理指令必须以“<?”作为开头以“?>”作为结尾XML声明语句就是最常见的一种处理指令。
l 所有XML 元素都须有关闭标签
l XML 标签对大小写敏感
l XML 必须正确地嵌套顺序
l XML 文档必须有根元素(只有一个)
l XML 的属性值须加引号
l 特殊字符必须转义--- CDATA
l XML 中的空格、回车换行会解析时被保留
什么是XML约束
在XML技术里可以编写一个文档来约束一个XML文档的书写规范这称之为XML约束。
为什么需要XML约束
常用的约束技术
XML DTD
XML Schema XSD
DTD的快速入门
1、先创建一个xml文件
2、书写一个DTD文件
dtd文件的扩展名必须是dtd
在xml中有多少个标签在dtd中就书写多少个ELEMNT
3、在xml文件中导入DTD的约束
DTD和xml文件的结合方式
使用内部DTD
可以把dtd和xml书写在同一个文件中
<!DOCTYPE 根标签名 [
写dtd的约束
] >
XML文件使用 DOCTYPE 声明语句来指明它所遵循的DTD文件DOCTYPE声明语句有两种形式
当引用的文件在本地时外部DTD采用如下方式
<!DOCTYPE文档根结点 SYSTEM "DTD文件的URL">
例如 <!DOCTYPE books SYSTEM“book.dtd”>。在xml文件中手写一下。
l 当引用的文件是一个公共的文件时公共DTD采用如下方式
<!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">
在DTD中使用 ELEMENT 声明当前xml中可以出现的标签名称 () 限制当前这个标签中的文本或者子标签。
告诉我们 当前的xml中可以有一个 books 标签在这个books标签下可以有一个或多个book子标签。
+ 当前括号中的这个标签可以出现一次或多次
当前括号中的这个标签可以出现零次或一次
* 当前括号中的这个标签可以出现零次或多次
括号中的逗号是在定义出现的子标签的顺序。
当前这个name标签中可以书写文本
<!ATTLIST 标签名
属性名 属性类型 属性约束
属性名 属性类型 属性约束
...
>
当前book标签上有一个abc属性这个属性的值是一个文本但是这个必须是必须书写的不能省略。
相关标签参考
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文档。
XML Schema 文件自身就是一个XML文件但它的扩展名通常为.xsd
和XML文件一样一个XMLSchema文档也必须有一个根结点但这个根结点的名称为Schema
应用schema约束 开发xml 过程
W3C预先定义元素和属性-àSchema文档模式文档约束文档-àXML文档实例文档
编写了一个XMLSchema约束文档后通常需要把这个文件中声明的元素绑定到一个地址上这个URI地址叫namespace名称空间以后XML文件就可以通过这个URI即名称空间引用绑定指定名称空间的元素
XML Schema文档基本结构
在W3C XML schema规范中规定所有的Schema文档都使用<schema>作为其根元素
<schema>元素可以包含一些属性。一个XMLschema声明看起来经常以如下的形式出现
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>
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.9</price>
</book>
</books>
声明文档空间
<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文件起名。
把targetNamespace属性的值做为当前 Schema文件的名称空间。
在xml文件中 需要 通过 xmlns 来引入不同名称下的Schema文件。
如果我们在同一个 xml文件中引入了多个Schema的名称空间这时需要大家给这些名称空间其别名。
如果在xml文件使用了多个 xmlns引入多个名称空间时需要在xmlns后面使用冒号给当前的名称空间起名。通过这个别区分到底当前xml中的标签受限于具体哪个Schema文件。
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。
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是一个开源、灵活的XML API。
目前很多开源框架如struts,hibernate都使用dom4j做为解析其xml的工具。
支持文档的读写功能和Xpath快速查询操作。
由于dom4j 它不是sun公司的技术而属于第三方公司的技术我们需要使用dom4j 就需要到dom4j官网下载dom4j的jar包。
把dom4jjar包拷贝我们的项目中
在自己的项目中新建一个lib文件把dom4j jar包拷贝到其中
把jar包添加到当前的classpath路径中
//注意以下类都来自于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);
//演示使用dom4j 获取 xml中的标签中的数据
publicstaticvoid getElement()throws Exception{
SAXReader reader = new SAXReader();
// 获取dom树
Document dom = reader.read("users.xml");
//获取xml中的根标签
Element root = dom.getRootElement();
//获取根标签下的所有子标签
List<Element> list =root.elements();
//遍历集合获取到每个 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());
}
}
//把最后一个user中的sex 修改为女
publicstaticvoid UpdateElement()throws Exception{
SAXReader reader = new SAXReader();
// 获取dom树
Document dom = reader.read("users.xml");
//先获取根标签
Element root = dom.getRootElement();
//获取 users 下的所有user标签
List<Element> list =root.elements();
//获取最后一个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();
}
// 删除
publicstaticvoid deleteElement() throws Exception {
SAXReader reader = new SAXReader();
// 获取dom树
Document dom = reader.read("users.xml");
// 删除最后一个user标签
// 先获取根标签
Element root = dom.getRootElement();
// 获取 users 下的所有user标签
List<Element> list = root.elements();
// 获取最后一个user标签
Element lastUser = list.get(list.size() -1);
root.remove(lastUser);
XMLWriter writer = new XMLWriter(newFileOutputStream("users.xml"));
writer.write(dom);
// 关流
writer.close();
}
// 创建一个新的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();
}
/**
* 这时一个工具类它的功能是完成对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树失败");
}
}
}
//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();
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对像
//以下选择所有的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());
//选择国家是 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文档如下
<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元素
l SAXStAX读取速度快。都是JAXP的成员。
l StAXIterator编程接口和Cursor编程接口。
l Dom4j。Dom。都会将所有节点加载加载到内存中。CRUD非常方便。
l Dom4j支持XPath.
本文出自 “IT技术解决方案” 博客,请务必保留此出处http://wyait.blog.51cto.com/12674066/1917046
原文地址:http://wyait.blog.51cto.com/12674066/1917046