XML技术学习
1.1XML简介
XML全称是 extensible markup language,可扩展标记语言
是一种标签语言。(类似HTML,实际上HTML上最开始一行!DOC那一行就是定义了HTML的约束文件,所以实际上HTML也是一种有约束的XML语言)
XML的标签是可以随便写的,一般用XML来信息的记录和传递。XML就是普通的文本文件,所以经常被用于做配置文件。使用简单的标记来描述数据。
1.2格式良好的XML
1.声明信息,用于描述XML的版本和编码方式.
2.XML要有且只有一个根元素(所谓元素,就是开始标签+内容+结束标签 或者是一个 单标签),值得一提的是XML是大小写敏感的,也就是说,大小写的标签是不一样的。
属性的值要使用双引号。
注释同HTML。
XML同样是一个树,也就是说XML的更元素同样只能有一个。
3.XML太自由了,所以必须要有对应的约束文件,XML才是有效的。
所以有效的XML文件必须是要用约束文件约束。
DTD约束
这里有一个问题,既然XML是随便定义标签的,那么一个公司里A写的和B写的有冲突怎么办?这个时候就要引入DTD约束的概念了,约束就是指定你某个标签必须怎么写,这样就算是不同的人写的XML,也是一样的。
DTD全称叫 document type defination叫文档类型定义。用于约束XML的文档格式。保证XML是一个有效的XML,也就是规范的XML定义。
DTD分为两种,一个叫内部DTD,一个叫外部DTD。
使用DTD
内部DTD的定义
语法很简单
<!DOCTYPE scores [写所有的元素声明和属性声明]>
其中scores是根元素,其中所有的元素声明和属性声明这样写
<!DOCTYPE scores [
<!ELEMENT scores (student)>
]>
注意了!scores和后面的子标签()之间必须有一个空格!!
这样给出了scores标签的定义,定义scores只能有一个student子标签,这个时候问题就来了,如果不写数量符,默认就是一个。那么我们的代码中想控制子标签的数量怎么办?
+ 表示一个或者多个(大于等于1)
?表示一次或零次(0/1)
* 表示出现任意次数(0/1/多次)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE scores [
<!ELEMENT scores (stduent+)>
<!ELEMENT stduent (name,course,score)>
<!ATTLIST stduent id CDATA #IMPLIED>
<!ELEMENT name (#PCDATA)>
<!ELEMENT course (#PCDATA)>
<!ELEMENT score (#PCDATA)>
]>
<scores>
<stduent id="1">
<name>张三</name>
<course>数据结构</course>
<score>88</score>
</stduent>
<stduent >
<name>李四</name>
<course>SQL必知必会</course>
<score>61</score>
</stduent>
</scores>
看看约束部分,很容易,对于属性的的限制只需要<!ATTLIST 那个标签 属性名 属性类型 属性的缺省值>
要求标签里面只能写文本不能写别的标签,只需要<!ELEMENT name (#PCDATA)>这样就可以了在强调以便name和()之间的空格
PCDATA的意思是parsed character data转换过的字符类型。
内部DTD就是这样了,按照约束去写,不同的人写的代码是一样的。这样大大提高了团队合作协同。
外部DTD
独立写一个my.dtd文件,如下
<!ELEMENT scores (stduent+)>
<!ELEMENT stduent (name, course, score)>
<!ATTLIST stduent id CDATA #IMPLIED>
<!ELEMENT name (#PCDATA)>
<!ELEMENT course (#PCDATA)>
<!ELEMENT score (#PCDATA)>
然后只需要在你想要引入这个约束文件的那个xml文件里面加一行这样的代码
<!DOCTYPE 本文档根便签名字 SYSTEM "my.dtd">
XSD
XML Schema是DTD的替代者,不经可以定义文档的结构,还可以规范文档的内容。
XSD本身也是XML
XML的解析
对XML文件进行操作,包括创建XML文件,对XML文件进行增删改查操作。
常见的XML解析技术有:
1.dom解析,比较耗费资源,适合多次访问XML,是基于XML树
2.SAX解析,是耗费资源少的,基于事件的解析,消耗资源少,适用于数据量较大的XML
这些用起来很麻烦,代码很多。
这时候就有了解析工具,
3.JDOM,里面有很多工具类,可以很方便通过里面的类来进行解析。开源,免费,效率比DOM解析块
4. DOM4J,这是我们要学的,4其实是英文中的谐音,为 DOM for Java,是JDOM的升级版,最好,所以我们学它。性能优异,功能强大,使用接口,而不是实现类。而且开源,免费。
DOM4J解析XML
最多的时候是查询操作(从XML提取出信息),有时候会把一些信息生成XML文件。
解析XML的入口是一个对象,是需要先拿到一个叫Document对象,也就是说,要用整个Document对象来表示一个XML文件。
读写主要依赖于org.dom4j.io
package com.bjsxt.xml;
import java.io.File;
import java.util.Iterator;
import org.dom4j.*;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class TestXML {
public static void main(String[] args) {
//创建SAXReader对象,用于读取xml文件
SAXReader reader=new SAXReader();
//读取XML文件,得到Document对象
try {
Document doc=reader.read(new File("src/scores2.xml"));
//获取根元素
Element root=doc.getRootElement();
//获取根元素下面的子元素
Iterator<Element> it=root.elementIterator();
while(it.hasNext()) {
//取出下一个元素
Element e=it.next();
//获取子元素,可以通过名字来获取
Element name=e.element("name");
Element course=e.element("course");
Element score=e.element("score");
System.out.println(name.getName()+"="+name.getText());
System.out.println(course.getName()+"="+course.getText());
System.out.println(score.getName()+"="+score.getText());
System.out.println("===========================");
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Dom4j生成一个XML文件
package com.bjsxt.xml;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import org.dom4j.*;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public class TestXML2 {
public static void main(String[] args) {
//通过DocumentHelper生成一个Document对象
Document doc=DocumentHelper.createDocument();
//添加根元素并得到根元素
Element root=doc.addElement("books");
for(int i=0;i<3;i++) {
Element book=root.addElement("book"+(i+1));
book.addAttribute("id", ""+i);
Element name=book.addElement("name");
Element author=book.addElement("author");
Element price=book.addElement("price");
name.addText("Thinking in Java");
author.addText("小狗");
price.addText("88");
}
//将doc输出到xml文件中即可
try {
OutputFormat format=OutputFormat.createPrettyPrint();
XMLWriter writer=new XMLWriter(new FileWriter(new File("src/book2.xml")),format);
writer.write(doc);
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}