一、Java解析xml、解析xml四種方法、DOM、SAX、JDOM、DOM4j、XPath
此文針對(duì)其中的DOM方法具體展開(kāi)介紹及代碼分析
sax、dom是兩種對(duì)xml文檔進(jìn)行解析的方法(沒(méi)有具體實(shí)現(xiàn),只是接口),所以只有它們是無(wú)法解析xml文檔的;jaxp只是api,它進(jìn)一步封裝了sax、dom兩種接口,并且提供了DomcumentBuilderFactory/DomcumentBuilder和SAXParserFactory/SAXParser(默認(rèn)使用xerces解釋器)。如果是嵌入式的情況下建議使用sax方法進(jìn)行解析,因?yàn)樗恍枰幌伦影褦?shù)據(jù)都保存到內(nèi)存中然后再解析是可以逐步解析的。而DOM不行,必須一次性把數(shù)據(jù)存到內(nèi)存中,然后一并解析。這樣做雖然速度會(huì)很快,但是同時(shí)也加大了對(duì)內(nèi)存的消耗。如果文件很大的情況下不建議DOM解析。
二、【DOM 簡(jiǎn)單使用介紹】
1、【DOM(Document Object Model) 】
由W3C提供的接口,它將整個(gè)XML文檔讀入內(nèi)存,構(gòu)建一個(gè)DOM樹(shù)來(lái)對(duì)各個(gè)節(jié)點(diǎn)(Node)進(jìn)行操作。
下面一段是DOM解析xml的一個(gè)案例一起來(lái)看一下。
【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
29
30
31
32
33
34
|
<? xml version = "1.0" encoding = "UTF-8" ?> < staffs > < staff id = "1" > < name >Tom_zhang1</ name > < age >19</ age > < sex >男</ sex > < phone >18677435526</ phone > < group > < id >1</ id > < name >Technical department</ name > </ group > </ staff > < staff id = "2" > < name >Susy_wang</ name > < age >18</ age > < sex >女</ sex > < phone >18962459987</ phone > < group > < id >2</ id > < name >Financial department</ name > </ group > </ staff > < staff id = "3" > < name >Jack_Ma</ name > < age >45</ age > < sex >男</ sex > < phone >1867755334</ phone > < group > < id >3</ id > < name >Financial department</ name > </ group > </ staff > </ staffs > |
【代碼】
Staff 類(lèi)
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
|
package Entity; public class Staff { private int id; private String name; private int age; private String sex; private String phone; private StuGroup group; public int getId() { return id; } public void setId( int id) { this .id = id; } public String getName() { return name; } public void setName(String name) { this .name = name; } public int getAge() { return age; } public void setAge( int age) { this .age = age; } public String getSex() { return sex; } public void setSex(String sex) { this .sex = sex; } public String getPhone() { return phone; } public void setPhone(String phone) { this .phone = phone; } public StuGroup getGroup() { return group; } public void setGroup(StuGroup group) { this .group = group; } public Staff() { super (); // TODO Auto-generated constructor stub } public Staff( int id, String name, int age, String sex, String phone, StuGroup group) { super (); this .id = id; this .name = name; this .age = age; this .sex = sex; this .phone = phone; this .group = group; } @Override public String toString() { return "Staff [age=" + age + ", group=" + group + ", id=" + id + ", name=" + name + ", phone=" + phone + ", sex=" + sex + "]" ; } } |
Group 類(lèi)
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
|
package Entity; public class Group { private int id; private String name; public int getId() { return id; } public void setId( int id) { this .id = id; } public String getName() { return name; } public void setName(String name) { this .name = name; } public Group() { super (); // TODO Auto-generated constructor stub } public Group( int id, String name) { super (); this .id = id; this .name = name; } @Override public String toString() { return "Group [id=" + id + ", name=" + name + "]" ; } } |
注釋?zhuān)?Staff類(lèi)不需解釋?zhuān)瑇ml文件中有幾個(gè)<>就需要?jiǎng)?chuàng)建幾個(gè)字段。Group類(lèi)的創(chuàng)建是因?yàn)間roup本身又是一個(gè)節(jié)點(diǎn),它有它自己的字段。因此在這邊把這種情況單獨(dú)作為一個(gè)類(lèi)創(chuàng)建,同時(shí)也方便日后維護(hù)管理。依次類(lèi)推如果有更多的子類(lèi),方法一樣創(chuàng)建相應(yīng)的類(lèi)即可。
無(wú)論是DOM解析還是SAX解析,都是通過(guò)一個(gè)叫做Parser的解釋器,來(lái)對(duì)xml文件進(jìn)行解析。而這個(gè)解析器是需要我們手動(dòng)創(chuàng)建的,接下來(lái)就一起來(lái)看一下解釋器中的代碼,也是最主要的代碼。
Dom_parser(解析器)
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
|
package Parser; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; 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; import Entity.StuGroup; import Entity.Staff; public class Dom_parser { public static List<Staff> parser(String fileName) { List<Staff> staffs = new ArrayList<Staff>(); //創(chuàng)建一個(gè)ArrayList來(lái)裝數(shù)據(jù) DocumentBuilderFactory factory = null ; //DocumentBuilderFactory,DocumentBuilder,Document分別是DOM解析的工廠類(lèi) DocumentBuilder builder = null ; Document doc = null ; Staff staff = null ; //方便日后實(shí)例化 StuGroup group = null ; //同上 try { factory = DocumentBuilderFactory.newInstance(); //工廠類(lèi)實(shí)例化 builder = factory.newDocumentBuilder(); //工廠類(lèi)實(shí)例化 doc = builder.parse( new File(fileName)); //通過(guò).parser方法加載文件 Element root = doc.getDocumentElement(); //Element方法中的.getDocumentElement()代表獲取xml文件的頭文件內(nèi)容 NodeList nodelist = root.getElementsByTagName( "staff" ); //獲取TagName,每一個(gè)<>中的字段為一個(gè)TagName.作為一個(gè)nodelist來(lái)保存 //循環(huán)這個(gè)NodeList,然后得到每個(gè)nodelist中的item。根據(jù)獲取到的值的索引最終通過(guò).set方法得到這個(gè)值 for ( int index = 0 ; index < nodelist.getLength(); index++) { staff = new Staff(); Node node = nodelist.item(index); staff.setId(Integer.parseInt(node.getAttributes().getNamedItem( "id" ).getTextContent())); // System.out.println(staff); NodeList childNode = node.getChildNodes(); //設(shè)置一個(gè)childNode為了存放nodelist下子<>中的TagName //同上循環(huán)子childNode這個(gè)list,獲取到每個(gè)元素的下標(biāo)。再通過(guò).set方法分別得到每個(gè)元素的值。 for ( int i = 0 ; i < childNode.getLength(); i++) { Node childitem = childNode.item(i); if (childitem.getNodeName().equals( "name" )) { staff.setName(childitem.getTextContent()); } else if (childitem.getNodeName().equals( "age" )) { staff.setAge(Integer.parseInt(childitem .getTextContent())); } else if (childitem.getNodeName().equals( "sex" )) { staff.setSex(childitem.getTextContent()); } else if (childitem.getNodeName().equals( "phone" )) { staff.setPhone(childitem.getTextContent()); } else if (childitem.getNodeName().equals( "group" )) { NodeList groupnode = childitem.getChildNodes(); for ( int j = 0 ; j < groupnode.getLength(); j++) { Node groupitem = groupnode.item(j); if (groupitem.getNodeName().equals( "id" )) { group = new StuGroup(); //這里的實(shí)例化很重要,切記不要實(shí)例化錯(cuò)誤地方 String groupId = groupitem.getTextContent(); group.setId(Integer.parseInt(groupId)); staff.setGroup(group); } else if (groupitem.getNodeName().equals( "name" )) { String groupName = groupitem.getTextContent(); group.setName(groupName); staff.setGroup(group); } } } } staffs.add(staff); //最終我們要把staff這個(gè)對(duì)象追加到staffs這個(gè)集合中。 } } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return staffs; //返回這個(gè)集合 } } |
【測(cè)試類(lèi)】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package Parser; import java.util.List; import Entity.Staff; public class Test { public static void main(String[] args) { String file = "C:/Users/IBM_ADMIN/Desktop/xml/staff.xml" ; //指定文件地址 List<Staff> staffs = Dom_parser.parser(file); //因?yàn)槲覀儎?chuàng)建的解析器的名字叫Dom_parser所以在這里調(diào)用Dom_parser.parser()方法。()中參數(shù)為文件地址。 //循環(huán)并打印結(jié)果 for (Staff list:staffs){ System.out.println(list); } } } |
【打印結(jié)果】
打印結(jié)果如下。可以看到xml中每個(gè)TageName以及對(duì)應(yīng)的值,通過(guò)DOM解析的方式把結(jié)果都一一的被獲取并打印出來(lái)了。
目前我們是把數(shù)據(jù)放到了ArrayList內(nèi)存中。后續(xù)可以把數(shù)據(jù)存放到數(shù)據(jù)庫(kù)中。
Staff [age=19, group=Group [id=1, name=Technical department], id=1, name=Tom_zhang1, phone=18677435526, sex=男]
Staff [age=18, group=Group [id=2, name=Financial department], id=2, name=Susy_wang, phone=18962459987, sex=女]
Staff [age=45, group=Group [id=3, name=Financial department], id=3, name=Jack_Ma, phone=1867755334, sex=男]
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://www.cnblogs.com/liupengpengg/p/6879193.html