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()方法只有一个输出流参数的时候,默认是追加模式哎 。
效果:
(3)Eclipse格式化代码的方法:source→format:
(4)Dom4j并不负责XML的校验工作
(1)上述,代码,如果写的时候,有违反XML约束的地方,也会照写,Dom4j并不负责XML的校验工作(DTD || Schema);所以聪明做法是,每次写完后,在IDE中,打开XML文档,看是否有问题:
如果在IDE中发现了错误,提醒及时检查书写代码;或者核验约束规则;