XML语言(可扩展标记语言W3C):描述一系列有关系的数据,允许自定义标签,它常用作软件配置文件,以描述程序模块之间的关系。
- XML语法:文档声明,元素,注释(DATA区,特殊字符,处理指令(processing instruction))
- 文档声明:声明文档的类型
- 例如:<?xml version="1.0"?> <?xml version = "1.0" encoding = "gb2312" ?>
- 乱码问题:XML文件写了encoding=utf-8,而文本文档默认系统的编码,即保存成了GB2312格式,则会出现乱码。
- 元素:XML文件中出现的标签
- 可以嵌套,但是不能交叉嵌套
- 可以带主体的标签<a>...</a>,也可以不带主体的<a />
- 必有且仅有一个根标签
- 标签中的换行和空格都是原始文件,不能格式混乱,即格式良好的方式在XML中要*改变。
- 标签规范:不能以数字和"_"开头,不能以xml(Xml或XML)开头,不能有空格,中间不含":"
- 属性:
- 属性值一定用"双引"或"单引"引起来
- 可以使用子标签,例如<input><name>...</name>
- 注释:<!-- -->声明之前不能有注释,不能有嵌套注释。
- CDATA区:内容解析引擎不会解析内容,原封不动输出。<用于程序>
- 文档声明:声明文档的类型
<![CDATA[内容]]> 例:<![CDATA[...<><>...]]>
- 转义字符:不要漏分号
& --> & < --> < > --> > " --> " ' -->'
- 处理指令(PI):处理指令用来指挥解析引擎如何解析XML文档内容。例:<?xml-stylesheet type="text/css" href="1.css" ?>声明语句也是处理指令。
- XML约束:框架的作者需要约束配置文件的编写格式
- DTD约束技术:Document Type Definition文档类型定义
<?xml version="1.0" ?> //XML文件
<!DOCTYPE 书架 SYSTEM "book.dtd"> <书架>
<书>
<书名>Java ...</书名>
<作者>张孝祥</作者>
<售价>39.00元</售价>
</书>
<书>
...
</书>
</书架>
<!ELEMENT 书架 (书+> //+表示一本或多本
<!ELEMENT 书 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
- DTD文件应使用UTF-8或Unicode编码,若不符合DTD规则,在浏览器下打开XML也能通过,所以应该使用Eclipse来校验。
- DTD约束有两种形式,可以写在xml中,也可以单独一个文件。
- XML文件使用DOCTYPE声明语句来指明它所遵循的DTD文件。
- <!DOCTYPE 文档根节点 SYSTEM "DTD文件的URL">引用的是本地文件。
- <!DOCTYPE 文档根节点 PUBLIC "DTD名称" "DTD文件的URL"> 引用的是公共文件。例如:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems.Inc. //DTD ...." "http://java.sun.com/dtd/web_app_2_3.dtd">
- DTD约束语法细节:(元素定义,属性定义,实体定义)
- 元素定义:在DTD文档中使用ELEMENT声明一个XML元素,语法为<!ELEMENT 元素名称 元素类型>
- 元素类型可以是元素内容或类型,如<!ELEMENT 书架(书名,作者,售价)> 和 <!ELEMENT 书名 (#PCDATA)> --> 元素内容需要用()括起来。EMPTY->用于定义空元素,ANY为任意类型->元素类型可以直接写。
- 元素内容的组成关系:用逗号分隔,表示出现顺序要一致;用"|"分隔,表示任选其一,只能出现其中一个。元素内容可以出现"+",表示一次或多次,"?"表示0次或一次,"*"表示0次或多次。
- 属性定义:XML文档中的标签需要通过ATTLIST为其设置属性。
- 语法:
- 元素定义:在DTD文档中使用ELEMENT声明一个XML元素,语法为<!ELEMENT 元素名称 元素类型>
- DTD约束语法细节:(元素定义,属性定义,实体定义)
<!ATTLIST 元素名
属性名1 属性值类型 设置说明
.......
>
如:
<!ATTLIST 商品
类别 CDATA(相当于String) #REQUIRED(必须设置的属性)
颜色 CDATA(相当于String) #IMPLIED(可选属性)
>
- 设置说明:#REQUIRED为必须设置该属性,#IMPLIED可以设置也可以不设置,#FIXED取值固定一个值,但是要提供这个值,并且直接使用默认值,可以默认也可以修改。例:
<!ATTLIST 页面作者
姓名 CDATA #IMPLIED
年龄 CDATA #IMPLIED
联系信息 CDATA #REQUIRED
网站职务 CDATA #FIXED "页面作者" //默认值可以不写
个人爱好 CDATA "上网" //默认值可以不写
>
- 属性值类型:CDATA --> 普通文本字符串 ENUMERATED --> 枚举(鸡肉|猪肉|牛肉) ID --> 标签的唯一标识,只能由字母开头,不能出现空格 ENTITY(实体) --> 创建一段内容的别名
- ENTITY定义语法:引用实体:<!ENTITY 实体名称 "实体内容">,以&实体名称; --> 实体内容方式在XML中引用。例如
- 属性值类型:CDATA --> 普通文本字符串 ENUMERATED --> 枚举(鸡肉|猪肉|牛肉) ID --> 标签的唯一标识,只能由字母开头,不能出现空格 ENTITY(实体) --> 创建一段内容的别名
<!ENTITY copyright "I am a programmer"> //在XML中使用©right;来引用
<!ENTITY %实体名称 "实体内容"> //以%实体名称; --> 实体内容方式引用
<!ENTITY %TAG_NAMES "姓名|E-MAILS|电话|地址">
<!ELEMENT 个人信息 (%TAG_NAMES;|生日)>
<!ELEMENT 客户信息 (%TAG_NAMES;|公司名)>
- XML编程(CRUD 增删改查):
- XML解析方式:dom和sax
- DOM(document object model):一上来就直接将文档加载到内存中,将所有元素都变成对象。内存消耗较大,但是增删改查很容易。特点:标签,文本,属性皆是对象。
- SAX(simple API for XML) :SAX官方说明,如果增删改,请用DOM。不是官方标准,但广泛使用sax。特点:读一行解析一行,内存消耗小,不适合增删改查。
- XML解析开发包:Jaxp(sun),Jdom,dom4j。其中,dom4j最好用。
- Jaxp:是J2SE的一部分,由javax.xml,org.w3c.dom,org.xml.sax包及子包组成。在javax.xml.parsers包中,定义了几个工厂类,程序员调用工厂类可以得到xml文档的DOM解析器和SAX解析器,从而实现了XML的解析。
- 实现:DocumentBuilderFactory抽象类调用newInstance方法获取工厂对象,在调用对象中的parse方法,返回一个DOM的Document对象,在用Document对象,实现XML文档的增删改查。而XML文档的保存,则使用Transform类的transform方法来解决。
- 代码:
- Jaxp:是J2SE的一部分,由javax.xml,org.w3c.dom,org.xml.sax包及子包组成。在javax.xml.parsers包中,定义了几个工厂类,程序员调用工厂类可以得到xml文档的DOM解析器和SAX解析器,从而实现了XML的解析。
- XML解析方式:dom和sax
Document doc = builder.parse("src/book.xml");
NodeList list = doc. getElementByTagName("书名");
Node node = list.item(1);
String content = node.getTextContent();
增删改查都可以参照API,Document,Node,Element,transform等完成。
- Sax解析:采用事件处理的方式解析XML文件,涉及解析器和事件处理器
- 解析器可以使用Jaxp的API创建,创建出SAX解析器去解析某个XML文档。
- 解析器采用SAX方式解析某个XML文档时,只要解析到XML文档的组成部分,就会去调用时间处理器的方法,并把内容传给时间处理器(参数传递)。
- 通过事件处理器的参数,可以获得解析后的数据,从而决定后续的操作。(事件处理器由程序员编写)
- 流程:SAXPARSERFactory --> SaxParser --> SaxReader -->Content Handle(传入XML文档) --> 事件处理器。事件处理器的编写可以查看API,Content Handle可以利用DefaultHandler继承,并覆盖start,character,end方法即可。
- javabean封装xml文档数据:
- 先新建javabean类,再重写DefaultHandler的start,character,end方法,以标签为条件判断,存入List中。注意在标签结束时,应清空记录的标签,否则在标签结束时,跳入空行中间字段,抛出空指针异常。
- Dom4j解析:(Hibernate就是使用dom4j解析配置文件):
- 首先在Jre中导入dom4j的jar包<注意其文件中的jar包和支持jar包都要导入>。可以查看Dom4j的文档,可以快速了解dom4j的编程。
- 乱码问题:保存数据如果有乱码问题,可以初步判断是IO流的问题,使用OutputStream(File,charset)来选择合适的编码方式。而XMLWriter.write采用UTF-8的方式写XML文件,所以若需要写XML文件以GB2312方式,需要定义format输出器。建议用字节流,因为如果用字符流,是由字符流来查码表。若用字节流,则是由XMLWriter来查码表。
- 增删改查:
- <Create>得到Root节点,再一次往下找要增加标签的父标签,若要加入标签到序列中,需要得到父标签的子标签集合{List=element();},再调用List的add方法插入至指定位置。
- <Delete>从根节点向下,指到要删除的结点,再找到父标签,调用remove方法。
- <Update>从根节点向下找到目的节点,调用setText()方法。
- XPath:快速定位XML数据 <XPATH TUTORIAL>文档
- 语法:单斜杠:从根元素开始写;双斜杠:从绝对路径开始 //* //BBB[属性] --> 插文档
- 代码:
- Sax解析:采用事件处理的方式解析XML文件,涉及解析器和事件处理器
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("...."));
doc.selectSingleNode("//作者"); //获取单个结点
doc.selectNodes("..."); //获取所有结点
- 匹配用户名密码:
Node node = document.selectSingleNode("//user[@username='"+password+"' and @password='"+password+"']");
if(node == null){
system.out.println("用户名密码错误");
}else{
....
}
- Schema约束:
- 特性:
- Schema符合XML语法结构(用XML约束XML)。
- 可以使用Dom4j等解析Schema(因为Schema本身就是个XML)
- Schema独有命名空间。Schema比DTD支持更多的数据类型,约束功能更强。
- 不能定义实体,且比DTD复杂。已成为W3C标准。
- 后缀名.xsd,一个Schema文档通常称之为模式文档,遵循文档的XML文件称为实例文档。
- XML Schema必须有根节点,并且一定是Schema名称。
- 在编写Schema文档后,需要将文档中声明的元素绑定到URI上,即把XML Schema文档声明的元素绑定到一个命名空间上,以便以后解析引擎找到解析方法。
- 名称空间:在Schema中,每个约束模式文档都可以被赋予一个唯一的名称空间,在XML书写标签时,可以通过名称空间声明(xmlns)来表明当前编写的标签来自哪个Schema文档。
- 特性:
- Schema约束:
<itcast:书架 xmlns:itcast="http://www.itcast.cn">
<itcast:书>....</itcast>
</itcast:书架>
- 为了找到具体文件的位置,需指定SchemaLocation属性。例:
<itcast:书架 xmlns:itcast="http://www.itcast.cn"
xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance"
xsi:schemalocation="http://www.itcast.cn book.xsd">
- 使用默认的名称空间:xmlns="URI"。例如:
<书架 xmlns="www.itcast.cn" > //指定了一个默认的名称空间
......
......
<书>....</书>
</书架>
- 使用名称空间引入多个XML Schema文档:多写一行xmlns,多谢一个SchemaLocation,可以使用两种约束文档。
- 不使用名称空间:<书架 xml:xsi=.... xsi:noNameSpaceSchemaLocation="xmlBook.xsd">
- Schema语法:查看w3c文档