使用DOM进行xml文档的crud(增删改查)操作<操作详解>

很多朋友对DOM有感冒,这里我花了一些时间写了一个小小的教程,这个能看懂,会操作了,我相信基于DOM的其它API(如JDOM,DOM4J等)一般不会有什么问题。

后附java代码,也可以下载(可点击这里入下载)导入到Eclipse或MyEclipse。

 

image

Node和Element的关系

  1. Element是Node的子接口,所以Element的方法要比Node方法要多,这样的话使用起来比较方便,一般情况我们都把节点转换成元素(或者叫标签,即Element);

    image

  2. Element是Node的子类型:

比如我们运行实例中的readByNode(Node node)方法,如果把类型断码if (node.getNodeType()==node.ELEMENT_NODE)注释掉,你会发现会输出以下内容:

输出内容包括文本类型(DOM会把空格也当做类型)和document类型及元素类型,如果只查找Element类型,可以使用判断Node类型,这个我们一定要注意!

我们从结果可以看出来 Element实际上是”<>”内的值。

节点类型常量字段值可对照Java  API文档的Node”常量字段值“查看:

image

 

 

修改xml后需要使用Transformer更新到xml文件中

因为DOM修改是在内存中修改,要更新到xml文件中,必须使用Transformer写入。除读以外,其它的增、删、改这些更新数据的操作必须Transformer更新到xml文件。

什么时候使用item(0)?

当我们使用通过getElementsByTagName得到的是子元素的集合,如果这个子元素集合中只有一个元素时我们可以使用item(0),当然我们指定item(0),因为item(0)是第一个元素集合中的第一个元素。

如何删除节点?

首先要获得要删除的节点,然后再得到其父节点,再使用父节点的removeChild方法删除要删除节点,所以删除是不能“自杀”大笑

如何创建节点?

首先使用DOM的createElement方法创建各个元素,然后通过appendChild方法让各个之间建立父子关系,这个关系不一定要从根节点开始,要看你如何增加,是否准确的找到插入位置就可以了。

 

-----------------------------------以下为xml代码-----------------------------------

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="utf-8" ?>
<students>
    <student id="001" sex="男">
        <name>周星驰</name>
        <age>23</age>
        <intro>这是一位成绩很好的学生</intro>
    </student>
    <student id="002" sex="男">
        <name>刘德华</name>
        <age>32</age>
        <intro>他综合能力很优秀</intro>
    </student>
    <student id="003" sex="女">
        <name>周惠敏</name>
        <age>31</age>
        <intro>长得漂亮</intro>
    </student>
    <student id="004" sex="男">
        <name>王五</name>
        <age>37</age>
        <intro>成绩有点差</intro>
    </student>
    <student id="005" sex="男">
        <name>张三丰</name>
        <age>26</age>
        <intro>经常逃课</intro>
    </student>
</students>

 

-----------------------------------以下为java代码-----------------------------------

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
package com.xmltest;
 
import java.io.File;
import java.io.IOException;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
 
// 注意不要导错包了
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
 
/**   
 * <b>项目:</b>使用DOM进行xml文档的crud(增删改查)操作<br />
 * <b>文件名:</b> Xml_Crud.java<br />
 * <b>类名:</b> Xml_Crud<br />
 * <b>包:</b> com.xmltest<br />
 * <b>描述:</b> 一个xml简单的crud操作<br />  
 * <hr />
 * <div align="left"><font color="#FF0000"><strong>xml的crud增删改查操作</strong></font></div>
 * <hr />
 * <b>时间:</b> 2014-12-1 上午9:45:45<br />
 * <b>Copyright:</b> 2014<br />
 * @author  javalittleman
 * @version V1.0
 */
public class Xml_Crud {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, TransformerException {
        File file = new File("src/student.xml");
        Document doc=doc(file);
        // 以下为【增\删\改\查】操作
        // 【查】一:通过node遍历
        // readByNode(doc);
        // 【查】二:通过传入第几个学生获得该学生下的所有信息
        // read(doc, 1);
        /* 【查】三:
         * 通过传入的学生姓名获得该学生的所有信息
         * 传入的为name元素的文本值
         */
        // read(doc,"刘德华");
        // 【删】一:通过序号删除
        // delete(doc, 1);
        // 【删】二:通过学生姓名删除
        // delete(doc, "张三丰");
        // 【增】:向xml中增加一个学生
        // creat(doc, "赵五", "男", "007", "21", "成绩一般,上课不太专心");
        // 【改】一:根据student的id属性修改xml文件
         updata(doc, "003", "周小明");
    }
     
    public static void readByNode(Node node){
        // 遍历时会把所有的text节点都输出
        // 加上node.getNodeType()==node.ELEMENT_NODE可输出元素节点
         if (node.getNodeType()==node.ELEMENT_NODE) {
            System.out.println("节点名:" + node.getNodeName());
            System.out.println("节点类型:" + node.getNodeType());
            System.out.println("节点值:" + node.getNodeValue());
         }
        NodeList nodeList=node.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node n = nodeList.item(i);
            readByNode(n);
        }
    }
 
    /**
     * <b>标题:</b> doc 方法 <br />
     * <b>描述:</b>生成DOM树的方法 <br />
     * <b>返回类型:</b>Document<br />
     *
     * @param file
     *            传入一个文件,在本实例中使用xml文件传
     * @return 返回一个DOM树
     * @throws ParserConfigurationException
     *             抛出解析配置错误异常
     * @throws SAXException
     *             抛出SAX异常
     * @throws IOException
     *             招聘IO异常
     */
    public static Document doc(File file) throws ParserConfigurationException, SAXException, IOException{
        // 创建解析工厂
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        // 创建解析器
        DocumentBuilder db = dbf.newDocumentBuilder();
        // 创建xml文件,得到一个DOM树
        Document doc = db.parse(file);
        // 返回DOM树
        return doc;
    }
     
    /**  
     * <b>标题:</b> tran 方法 <br />
     * <b>描述:</b>用于将内存中的DOM写入xml文件中 <br />
     * <b>返回类型:</b>void<br />
     * @param doc 内存中的DOM树
     * @param file 目标文件
     * @throws TransformerException 抛出转换异常
     */
    public static void tran(Document doc,File file) throws TransformerException{
        TransformerFactory tff = TransformerFactory.newInstance();
        Transformer tf = tff.newTransformer();
        tf.setOutputProperty(OutputKeys.ENCODING, "utf-8");
        DOMSource xmlSource = new DOMSource(doc);
        StreamResult streamresult = new StreamResult(file);
        tf.transform(xmlSource, streamresult);
    }
     
    /**  
     * <b>标题:</b> 【查】一:read 方法一 <br />
     * <b>描述:</b>通过学生的序号读出学生信息 <br />
     * <b>返回类型:</b>void<br />
     * @param doc DOM树
     * @param itemNum 传入的第itemNum个学生
     * @throws  无
     */
    public static void read(Document doc,int itemNum){
        //获取第itemNum-1个student元素,比如itemNum为我设1,那么就是第0个元素
        Element student=(Element) doc.getElementsByTagName("student").item(itemNum-1);
        if (student!=null) {
            // 获得其id属性值
            String id=student.getAttribute("id");
            // 获得其sex属性值
            String sex=student.getAttribute("sex");
            // 分别获得第itemNum-1个元素下的name、age、intro的文本值
            // 因为第itemNum-1个student下只有一个name元素,所以使用item(0),age和intro亦然
            String name = (String) student.getElementsByTagName("name").item(0).getTextContent();
            String age = (String) student.getElementsByTagName("age").item(0).getTextContent();
            String intro = (String) student.getElementsByTagName("intro").item(0).getTextContent();
            // 分别打印id、sex、name、intro值
            System.out.println(id + " " + name + " " + sex + " " + age + "岁 "+intro);
        }else {
            System.out.println("第“"+itemNum+"位”学生不存在");
        }
    }
 
    /**  
     * <b>标题:</b> 【查】二: read 方法二 <br />
     * <b>描述:</b>通过给出的学生姓名读取xml <br />
     * <b>返回类型:</b>void<br />
     * @param doc DOM树
     * @param studentNmae 传入学生姓名
     * @throws  无
     */
    public static void read(Document doc, String studentNmae) {
        //首先获得student元素
        NodeList student = doc.getElementsByTagName("student");
        /*
         * 遍历所有student节点下,找出其下的name元素
         * 是否有与传入studentName相同
         * 如果有就获取其id、sex、name、age、intro
         *          --------思路--------
         * 从遍历中获得name的文本为对应给出的studentName值后,取得name文本值
         * 再获得其父节点,然后才得到id、sex、age、intro的文本值
         */
        boolean isFund = false;
        String name=null;
        String sex=null;
        String id=null;
        String age=null;
        String intro=null;
        for (int i = 0; i < student.getLength(); i++) {
            Element ele = (Element) student.item(i);
            Element name_ele=(Element) ele.getElementsByTagName("name").item(0);
            name=name_ele.getTextContent();
            if (studentNmae.equals(name_ele.getTextContent())) {
                // 如果找到我们要找的学生姓名就取得其父元素,即student元素
                Element me=(Element) name_ele.getParentNode();
                sex=me.getAttribute("sex");
                id=me.getAttribute("id");
                // 因为每个student下只有一个age和intro元素,所以采用item(0)
                age= me.getElementsByTagName("age").item(0).getTextContent();
                intro=me.getElementsByTagName("intro").item(0).getTextContent();
                isFund=true;
                break;
            }
        }
        if (isFund) {
            System.out.println(id + " " + name + " " + sex + " " + age + "岁 " + intro);
        } else {
            System.out.println("没有找到“" + studentNmae + "”这个学生");
        }
    }
     
    /**  
     * <b>标题:</b>【删】一: delete 方法一 <br />
     * <b>描述:</b>根据传入的第几个元素进行删除 <br />
     * <b>返回类型:</b>void<br />
     * @param doc 传入的DOM树
     * @param studentNum 传入的第几个学生,也就是第几个元素
     * @throws TransformerException 抛出转换异常
     */
    public static void delete(Document doc,int studentNum) throws TransformerException{
        Element ele = (Element) doc.getElementsByTagName("student").item(studentNum-1);
        if (ele != null) {
            ele.getParentNode().removeChild(ele);
            System.out.println("删除成功");
        } else {
            System.out.println("该第" + studentNum + "位不存在,不能删除");
        }
        tran(doc, new File("src/student.xml"));
    }
     
    /**  
     * <b>标题:</b>【删】二: delete 方法二 <br />
     * <b>描述:</b>给出某个学生姓名进行删,即根据文本值删除 <br />
     * <b>返回类型:</b>void<br />
     * @param doc
     * @param studentName
     * @throws TransformerException
     * @throws  无
     */
    public static void delete(Document doc,String studentName) throws TransformerException{
        NodeList nodelist = doc.getElementsByTagName("name");
        boolean isFund=false;
        Element ele=null;
        for (int i = 0; i < nodelist.getLength(); i++) {
            ele = (Element) nodelist.item(i);
            if (studentName.equals(ele.getTextContent())) {
                isFund=true;<br>                   break;
            }
        }
        if (isFund) {
            ele.getParentNode().getParentNode().removeChild(ele.getParentNode());
            tran(doc, new File("src/student.xml"));
            System.out.println("已经删除“"+studentName+"”这位同学的信息");
        } else {
            System.out.println("找不到“" + studentName + "”这位学生,不能删除");
        }
    }
     
    /**  
     * <b>标题:</b>【增】 updata 方法 <br />
     * <b>描述:</b>向xml文件中增加信息 <br />
     * <b>返回类型:</b>void<br />
     * @param doc 传入的DOM树
     * @param name 姓名标签
     * @param sex student标签的性别属性
     * @param id student标签的id属性
     * @param age 年龄标签
     * @param intro 介绍标签
     * @throws TransformerException
     */
    public static void creat(Document doc,String name,String sex,String id,String age,String intro) throws TransformerException{
        // 找到根节点,根节点只有一个所以使用item(0)
        Element root=(Element) doc.getElementsByTagName("students").item(0);
        // 创建各个节点
        Element ele_student=doc.createElement("student");
        ele_student.setAttribute("id", id);
        ele_student.setAttribute("sex", sex);
        Element ele_name=doc.createElement("name");
        ele_name.setTextContent(name);
        Element ele_age=doc.createElement("age");
        ele_age.setTextContent(age);
        Element ele_intro=doc.createElement("intro");
        ele_intro.setTextContent(intro);
        // 使用appenChild方法增加父子关系
        root.appendChild(ele_student);
        ele_student.appendChild(ele_name);
        ele_student.appendChild(ele_age);
        ele_student.appendChild(ele_intro);
        // 写入xml文件
        tran(doc, new File("src/student.xml"));
        System.out.println("“"+name+"”同学的信息已经增加成功!");
    }
     
    /**  
     * <b>标题:</b>【改】: updata 方法<br />
     * <b>描述:</b>根据标签的属性值修改xml文件 <br />
     * 根据标签的文本值去修改其文本值这里就省略了<br />
     * <b>返回类型:</b>void<br />
     * @param doc 传入DOM树
     * @param id 传入student的id属性值
     * @param newName 传入新学生姓名
     * @throws TransformerException 抛出转换异常
     */
    public static void updata(Document doc,String id,String newName) throws TransformerException{
        boolean isFund=false;
        // 获得student节点集合
        NodeList stu=doc.getElementsByTagName("student");
        // 遍历student集合,并从中获得其id属性为传入的id值的元素,然后修改其元素下的name的文本值
        for (int i = 0; i < stu.getLength(); i++) {
            Element ele_stu=(Element) stu.item(i);
            if (id.equals(ele_stu.getAttribute("id"))) {
                ele_stu.getElementsByTagName("name").item(0).setTextContent(newName);
                isFund=true;
                break;
            }
        }
        if (isFund) {
            // 写入xml文件
            tran(doc, new File("src/student.xml"));
            System.out.println("修改成功");
        } else {
            System.out.println("不存在这个“" + id + "”ID属性值,修改失败!!!");
        }
    }
}

转载请注意出处或作者,谢谢!

posted @   爪哇小汉  阅读(2557)  评论(2编辑  收藏  举报
点击右上角即可分享
微信分享提示