up:: Dom4j读取XML文档
一:需求:加入现在来了个新员工,如果利用Dom4j将新员工的信息,写入到XML文档中?
1.XML文档:这个可以不看,只是贴这儿了;
<? xml version = "1.0" encoding = "UTF-8" ?>
<!-- 人力资源管理系统 --><!--xmlns:xsi的意思是告诉XML文档,我们的约束是使用Schema;xsi:noNamespaceSchemaLocation:指向xsd文件 -->
< hr xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation = "hr-schema.xsd" >
< employee no = "3306" > <!-- 标签和属性尽量起的有意义,做到见名知意 -->
< name >张三</ name >
< age >31</ age >
< salary >4000</ salary >
< department > <!-- 标签可以嵌套 -->
< dName >会计</ dName >
< dAddress >4楼103室</ dAddress >
</ department >
</ employee >
< employee no = "3377" >
< name >李四</ name >
< age >29</ age >
< salary >5000</ salary >
< department >
< dName >工程部门</ dName >
< dAddress >4楼105室</ dAddress >
</ department >
</ employee >
< employee no = "3346" >
< name >李铁柱</ name >
< age >35</ age >
< salary >4300</ salary >
< department >
< dName >行政部门</ dName >
< dAddress >3楼301室</ dAddress >
</ department >
</ employee >
</ hr >
2.XML Shema约束,xsd文件:这个可以不看,只是贴这儿了
<? xml version = "1.0" encoding = "UTF-8" ?>
< schema xmlns = "http://www.w3.org/2001/XMLSchema" >
< element name = "hr" > <!-- 声明根节点 -->
< complexType > <!-- complexType标签的意思是复杂节点,包含子节点时,必须使用这个标签 -->
< sequence > <!-- sequence是序列的意思,代表里面的子节点必须按照顺序书写 -->
<!-- minOccurs="1":employee节点最少出现一次;maxOccurs="9999":employee节点最多出现9999次-->
< element name = "employee" minOccurs = "1" maxOccurs = "9999" >
< complexType >
< sequence >
< element name = "name" type = "string" ></ element > <!-- type="string":name节点的值只能是字符串; -->
< element name = "age" >
< simpleType > <!-- 如年龄,要求在18-60之间; <simpleType>标签可以设置数值范围-->
< restriction base = "integer" > <!-- 这儿的base="integer"表示我们要限定范围的数据是整数-->
< minInclusive value = "18" ></ minInclusive >
< maxInclusive value = "60" ></ maxInclusive >
</ restriction >
</ simpleType >
</ element > <!-- Schema高级的地方就是有了数据类型 -->
< element name = "salary" type = "integer" ></ element >
< element name = "department" >
< complexType >
< sequence >
< element name = "dName" type = "string" ></ element >
< element name = "dAddress" type = "string" ></ element >
</ sequence >
</ complexType >
</ element >
</ sequence >
<!--在employee标签中有一个no属性,那么就在employee标签的那个 </complexType>标签位置上面设置attribute标签-->
<!-- “required”代表必须的,即任何employee标签如果不写no属性,会报错 -->
< attribute name = "no" type = "string" use = "required" ></ attribute >
</ complexType >
</ element >
</ sequence >
</ complexType >
</ element >
</ schema >
3.追加的方法:(核心,这篇博客可以只看这儿)
(1)代码:本篇博客的核心,最重要的部分
利用Dom4j追加XML文档:以后记不清了,可以作为一个查阅、参考的备忘;熟能生巧,熟练了就好了;
public class HrWriter {
public void writeXml () {
String file = "e:/eclipse-workspace/xml/src/hr-schema.xml" ;
//(1) SAXReader是读取XML文件的核心类,用于将XML解析后以“树”的形式保存在内存中。
SAXReader reader = new SAXReader ();
try {
// (2) SAXReader类的主要方法时read()方法,该方法返回一个Document对象;
Document document = reader. read (file);
// (3) 获取XML文档的根节点;Dom4j中所有的标签都是用Element类型来进行的包装;
Element root = document. getRootElement ();
// (4) 在根节点下,利用addElement()方法,创建一个新的“employee”子节点;这个方法返回这个新创节点的Element对象,以后续操作;
// 此后,在内存中,就有了一个新的空的“employee”节点(即一个空的Element对象)
Element employee = root. addElement ( "employee" );
// (5) 给新创的employee节点,设置属性
employee. addAttribute ( "no" , "3346" );
// (6) 给新创的employee节点,添加“name”子节点
Element name = employee. addElement ( "name" );
// (7) 给“name”子节点,设置文本;
name. setText ( "李铁柱" );
employee. addElement ( "age" ). setText ( "35" );
employee. addElement ( "salary" ). setText ( "4300" );
// (7.1) 添加嵌套的子节点
Element department = employee. addElement ( "department" );
department. addElement ( "dName" ). setText ( "行政部门" );
department. addElement ( "dAddress" ). setText ( "3楼301室" );
// (8) 上面设置完成后,代码一运行,就在内存中,构建出“李铁柱”这个员工节点,并追加到Document文档的最后;
// 但是,只在内存中是不行的,还要写到XML文件中去!
Writer writer = new OutputStreamWriter ( new FileOutputStream (file), "UTF-8" ); // 这个会抛FileNotFoundException异常
document. write (writer); // 这个会抛 IOException;可以增加几个catch,也可以只抛一个Exception
writer. close ();
} catch (Exception e ) {
// TODO Auto-generated catch block
e. printStackTrace ();
}
}
public static void main ( String [] args ) {
new HrWriter (). writeXml ();
}
}
(2)简单归纳:新的主要的东西有:
● Element employee = root.addElement(“employee”); 在根节点下,新加一个“employee”节点;
● employee.addAttribute(“no”, “3346”); 给新加的“employee”节点设置属性 ;
● Element name = employee.addElement(“name”); 给“employee”节点,添加“name”子节点 ;
● name.setText(“李铁柱”); 设置“name”子节点的值;
● Element department = employee.addElement(“department”);
department.addElement(“dName”).setText(“行政部门”);
给“employee”节点添加“department”子节点;因为“department”还有子节点,所以,继续向“department”添加“dName”子节点;;;;
节点都是Element对象,这种标签的一级一级的嵌套,
可以给每个Element对象再设置Element对象(有点一个根节点,多条发散的树状链表的赶脚) ;而且这种一个套一个,套娃。。。。
● Writer writer = new OutputStreamWriter(new FileOutputStream(file),“UTF-8”); 建立输出流,utf-8保证中文;
● document.write(writer); 内存中Document的内容,写到XML文件中去;然后发现,document的write()方法只有一个输出流参数的时候,默认是追加模式哎 。
效果:
(4)Dom4j并不负责XML的校验工作
(1)上述,代码,如果写的时候,有违反XML约束的地方,也会照写,Dom4j并不负责XML的校验工作(DTD || Schema);所以聪明做法是,每次写完后,在IDE中,打开XML文档,看是否有问题:
如果在IDE中发现了错误,提醒及时检查书写代码;或者核验约束规则;