前言
- 学习解析XML文件时,对于网上的各种xml解析方法,测一下他们的性能,还是有必要的,这也能方便我们以后对XML解析方法进行选择
- 对于Android平台来说,性能和占有内存是一个非常重要的指标
测试
本次要测试的xml文件
<?xml version="1.0" encoding="utf-8"?>
<data>
<action value="大家请看这里,哈哈哈1">
<array>
<name type="号码">1号</name>
<name type="号码">2号</name>
</array>
<array>
<name>开始咯!</name>
<name>开始咯!</name>
<name>开始咯!</name>
</array>
</action>
<action value="再来看看这里,哈哈哈2" >
<array>
<name type="号码">1号</name>
<name type="号码">2号</name>
</array>
<array>
<name>进行中!</name>
<name>进行中!</name>
<name>进行中!</name>
</array>
</action>
<action value="最后请看这里,哈哈哈3">
<array>
<name type="号码">1号</name>
<name type="号码">2号</name>
</array>
<array>
<name>结束啦!</name>
<name>结束啦!</name>
<name>结束啦!</name>
</array>
</action>
</data>
- 测试内容:
解析XML文件,并打印出所有节点名称 - 因为不想搞得太过复杂,所以只要求在遍历XML文件的节点时(所有节点),打印出节点的名称即可
不敢保证测试结果一定正确,不过大家可以去自行测试,验证你的猜想
Dom
- 首先是我们的第一位选手Dom
- 这位选手十分傲气,抛出的代码显得比较繁琐,但每层循环基本都是一样的,所以也并不难理解,具体如下:
long start=System.currentTimeMillis();
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc=builder.parse(new File("/storage/emulated/0/360/样本.xml"));
Element root=doc.getDocumentElement();
System.out.println(root.getNodeName());
NodeList list_action=root.getElementsByTagName("action");
for (int i=0;i < list_action.getLength();i++)
{
Element action=(Element) list_action.item(i);
System.out.println(action.getNodeName());
NodeList list_array=action.getElementsByTagName("array");
for (int j=0;j < list_array.getLength();j++)
{
Element array=(Element) list_array.item(j);
System.out.println(array.getNodeName());
NodeList list_name=array.getElementsByTagName("name");
for (int k=0;k < list_name.getLength();k++)
{
Element name=(Element) list_name.item(k);
System.out.println(name.getNodeName());
}
}
}
long end=System.currentTimeMillis();
long time=end - start;
System.out.println("共耗时" + time + "ms");
次数 | 耗时 |
---|---|
1 | 20ms |
2 | 10ms |
3 | 5ms |
4 | 8ms |
5 | 4ms |
6 | 5ms |
7 | 5ms |
8 | 5ms |
9 | 4ms |
10 | 6ms |
… | 4ms~8ms |
Pull
- 然后登场的是pull
- 这是一个被Google选择的xml解析器,它又会得我们带来怎样的精彩呢?
long start=System.currentTimeMillis();
XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
XmlPullParser parser=factory.newPullParser();
/*或者上面也可以写成(仅限Android项目)
XmlPullParser Parser=Xml.newPullParser();
*/
InputStream input=new FileInputStream(new File("/storage/emulated/0/360/样本.xml"));
parser.setInput(input, "utf-8");
int eventType=parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT)
{
switch (eventType)
{
//文档开始事件
case XmlPullParser.START_DOCUMENT:
{
}
break;
//元素开始事件
case XmlPullParser.START_TAG:
{
String TAG=parser.getName();
System.out.println(TAG);
}
break;
//元素结束事件
case XmlPullParser.END_TAG:
{
}}
eventType = parser.next();
}
long end=System.currentTimeMillis();
long time=end - start;
System.out.println("共耗时" + time + "ms");
次数 | 耗时 |
---|---|
1 | 2ms |
2 | 4ms |
3 | 2ms |
4 | 2ms |
5 | 4ms |
6 | 3ms |
… | 2~4ms |
Dom4j
- 最后一位登场的是Dom4j
- 由于安卓内部并没有集成这个,所以如果需要使用的话,我们还需要导一下包
- 与Dom相比,它的功能要更强,使用更简单,具体大家可以自行体验
Dom4j解析到带有多个属性值的元素时会报错,但基本并不影响使用,除非特殊情况
- 使用递归方法
start=System.currentTimeMillis();
SAXReader sax=new SAXReader();
Document doc=sax.read(new File("/storage/emulated/0/360/样本.xml"));
Element root=doc.getRootElement();
parse(root);
long end=System.currentTimeMillis();
long time=end-start;
System.out.println("共耗时"+time+"ms");
private static void parse(Element e)
{
System.out.println(e.getName());
for(Element element:e.elements()){
parse(element);
}
}
- 使用for循环的方法
long start=System.currentTimeMillis();
SAXReader sax=new SAXReader();
Document doc=sax.read(new File("/storage/emulated/0/360/样本.xml"));
Element root=doc.getRootElement();
System.out.println(root.getName());
List<Element>list_action=root.elements("action");
for(int i=0;i<list_action.size();i++){
Element action=list_action.get(i);
System.out.println(action.getName());
List<Element> List_array=action.elements("array");
for(int j=0;j<List_array.size();j++){
Element array=List_array.get(j);
System.out.println(array.getName());
List<Element>list_name=array.elements("name");
for(int k=0;k<list_name.size();k++){
Element name=list_name.get(k);
System.out.println(name.getName());
}
}
}
long end=System.currentTimeMillis();
long time=end-start;
System.out.println("共耗时"+time+"ms");
次数 | 耗时 |
---|---|
1 | 150ms |
2 | 135ms |
3 | 127ms |
4 | 107ms |
5 | 124ms |
6 | 115ms |
7 | 101ms |
8 | 142ms |
9 | 118ms |
10 | 96ms |
11 | 94ms |
12 | 115ms |
13 | 108ms |
14 | 129ms |
15 | 105ms |
… | 数值不稳定 |
Dom4j虽然解析速度慢了点,但功能方面还是很强的,API也比较简单,还是很方便的