一. 前言

1. DOM解析

DOM 解析是把文件一次性加载到内存里,生成一个树状结构,在内存中对树状节点进行修改或添加节点。所以,这种方法的缺点是消耗的内存太大。

2. 常用的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DocumentBuilder抽象类
/**
* Parse the content of the given <code>InputStream</code> as an XML
* document and return a new DOM {@link Document} object.
* An <code>IllegalArgumentException</code> is thrown if the
* <code>InputStream</code> is null.
*
* @param is InputStream containing the content to be parsed.
* @return <code>Document</code> result of parsing the
* <code>InputStream</code>
* @exception IOException If any IO errors occur.
* @exception SAXException If any parse errors occur.
* @see org.xml.sax.DocumentHandler
*/
public Document parse(InputStream is)
1
2
3
4
5
6
7
8
9
10
11
12
13
Document接口
/**
* Returns a <code>NodeList</code> of all the <code>Elements</code> in
* document order with a given tag name and are contained in the
* document.
* @param tagname The name of the tag to match on. The special value "*"
* matches all tags. For XML, the <code>tagname</code> parameter is
* case-sensitive, otherwise it depends on the case-sensitivity of the
* markup language in use.
* @return A new <code>NodeList</code> object containing all the matched
* <code>Elements</code>.
*/
public NodeList getElementsByTagName(String tagname);
1
2
3
4
5
6
7
8
9
10
11
NodeList接口
/**
* Returns the <code>index</code>th item in the collection. If
* <code>index</code> is greater than or equal to the number of nodes in
* the list, this returns <code>null</code>.
* @param index Index into the collection.
* @return The node at the <code>index</code>th position in the
* <code>NodeList</code>, or <code>null</code> if that is not a valid
* index.
*/
public Node item(int index);
1
2
3
4
5
6
Node接口
/**
* A <code>NamedNodeMap</code> containing the attributes of this node (if
* it is an <code>Element</code>) or <code>null</code> otherwise.
*/
public NamedNodeMap getAttributes();
1
2
3
4
5
6
Node接口
/**
* The first child of this node. If there is no such node, this returns
* <code>null</code>.
*/
public Node getFirstChild();
1
2
3
4
5
6
7
8
9
10
11
Node接口
/**
* The value of this node, depending on its type; see the table above.
* When it is defined to be <code>null</code>, setting it has no effect,
* including if the node is read-only.
* @exception DOMException
* DOMSTRING_SIZE_ERR: Raised when it would return more characters than
* fit in a <code>DOMString</code> variable on the implementation
* platform.
*/
public String getNodeValue() throws DOMException;

二. 实际小例子

1. 待解析的Xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<web>
<item id="0" url="https://www.baidu.com">百度</item>
<item id="1" url="https://www.taobao.com">淘宝</item>
<item id="2" url="https://www.qq.com">腾讯</item>
<item id="3" url="https://www.aili.com">阿里巴巴</item>
<item id="4" url="https://www.taobao.com">淘宝</item>
<item id="5" url="https://www.wechat.com">微信</item>
<item id="6" url="https://www.timi.com">天美</item>
<item id="7" url="https://www.guangzi.com">光子</item>
<item id="8" url="https://www.taoken.com">字节跳动</item>
<item id="9" url="https://www.douyin.com">抖音</item>
</web>

2. Activity中的调用

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
public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//DOM解析
testDOMParse();
}

/**
* DOM解析
*/
private void testDOMParse(){
//存储解析的模型资源
List<WebItem> webItems = new ArrayList<>();

//临时的模型类
WebItem webItem = null;

try {
//创建一个DocumentBuilder工厂类
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

//根据DocumentBuilder工厂类创建DocumentBuilder
DocumentBuilder db = dbf.newDocumentBuilder();

//使用DocumentBuilder加载xml文件
Document document = db.parse(getResources().openRawResource(R.raw.test));

//获取所有的item节点集合
NodeList items = document.getElementsByTagName("item");

//遍历每一个item节点
for (int i = 0; i < items.getLength(); i++) {
//初始化模型类
webItem = new WebItem();

//获取一个具体的item
Node item = items.item(i);

//获取一个item的所有属性集合
NamedNodeMap attrs = item.getAttributes();

//遍历item的所有属性
for (int j = 0; j < attrs.getLength(); j++) {
//获取某个属性
Node node = attrs.item(j);
//获取节点属性名
String nodeName = node.getNodeName();
//获取节点属性值
String nodeValue = node.getNodeValue();

if (TextUtils.equals(nodeName,"id")){
webItem.setId(Integer.parseInt(nodeValue));
}

if (TextUtils.equals(nodeName,"url")){
webItem.setUrl(nodeValue);
}
}

//获取item的值
String content = item.getFirstChild().getNodeValue();
webItem.setContent(content);

//加入集合
webItems.add(webItem);
}

} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

for (WebItem item : webItems) {
//Toast.makeText(this, "id:"+item.getId()+" url:"+item.getUrl()+" content:"+item.getContent(), Toast.LENGTH_SHORT).show();
//显示数据
addToRootLayout((LinearLayout) findViewById(R.id.root),item);
}
}

/**
* 将WebItem显示到布局中
* @param layout
* @param webItem
*/
private void addToRootLayout(LinearLayout layout, WebItem webItem){
View inflate = LayoutInflater.from(this).inflate(R.layout.web_item_layout, null);
TextView id_text = inflate.findViewById(R.id.id);
TextView content_text = inflate.findViewById(R.id.content);
TextView url_text = inflate.findViewById(R.id.url);

id_text.setText(String.valueOf(webItem.getId()));
content_text.setText(webItem.getContent());
url_text.setText(webItem.getUrl());

layout.addView(inflate);
}
}

3. 运行结果

4. 源码地址

ParseXml

参考文章

xml文件解析—DOM方式