admin 管理员组

文章数量: 1086019


2024年4月20日发(作者:减速机滑块联轴器)

< ≮ 曼Yl墨 c! 里 缠塞 

解析大数据量XML文件的实现 

◆张二松缪红萍宋梦馨 

摘要:信息系统在解析大数据量的xML文件时,容易发生内存溢 

出问题。本文详细介绍了如何通过SAX方式解析大数据量的XML文件。 

SAX是一种消耗内存较小的解析方式。它能有效解决由于大量消耗内存 

而导致的内存溢出问题。 

关键词:SAX;dom4j;大数据量;内存溢出 

<?xml version=”1.0”encoding=”gb23 12”?> 

引言 

<root> 

XML文件被广泛应用于信息系统之间传递数据。 

<application name=”sale”> 

信息系统接收到xML文件,在进行解析后才能加载数 

<seller name=”SuperMarketA.xml’’> 

据。当XML文件中的数据量较小时,多种解析方式都 

<product name="coffee”> 

能够完成解析XML文件。然而,随着XML文件中的数 

<attribute>price</attribute> 

据量的不断增大,有些解析方式消耗的内存也越来越 

<attribute>brand</attribute> 

大,由于超出了内存的处理能力,最终会出现内存溢出 

<attribute>weight</attribute> 

问题。在解析XML文件的各种方式中,SAX方式在解 

</product> 

析大数据量的XML文件上具有优势。它不需要将整个 

<product name=”milk”saveasname=”freshmilk”> 

XML文件加载到内存里面,占用的内存比较少,因此 

<attribute>price</attribute> 

它适合解析大数据量的XML文件。 

<attribute>brand</attribute> 

本文以解析包含了大量商品信息的XML文件(包括 

<attribute>specifications</attribute> 

SuperMarketA.xml、SuperMarketB.xml、SuperMarketC. 

</product> 

xm1)为例,首先建立这& ̄XML文件的配置文件(config. 

xm1),然后使用SAX方式解析这些XML文件。 

</seller> 

<seller name=”SuperMarketB.xml”> 

二、创建XML配置文件 

在实际应用中,XML文件里面的标记信息,有时 

</seller> 

会因业务需要而做调整。当这些XML文件中的标记变 

<seller/lame=”SuperMarketC.xml’’> 

更时,解析XML文件的程序源文件也需要做相应的修 

改,因此,程序源文件需要重新编译才能使用。为了 

</seller> 

防止修改程序源文件,建立一个配置文件,也就是把 

</application> 

XML文件中的所有标记全部存储到一个XMLi ̄置文 

</root> 

件中。在程序源文件中,不再写入XML文件的标记信 

息,而是当需要标记信息时直接从配置文件中获取。这 

config.xml配置文件的数据量只有几十k大小,可 

样,当标记变更时,只需要在配置文件中进行修改,而 

以不用考虑内存消耗问题。本文使用dom4j方式解析 

不用修改程序源文件。 

config.xml文件,它具有简单易用、访问灵活等特点。 

XML配置文件除了可以进行灵活的扩展变化,还 首先创建类文件Dom4jParse.java,然后在类 

可以反映清晰的层级嵌套关系。下面的XML配置文件 

中建立两个方法:getAttribute0和getElement()。其 

(config.xm1)反映了四个层级关系:销售、销售公司、产 中,getAttribute0方法用于获取元素的name属性值 

品、产品的属性。config.xmllf?,置文件如下: (如:application元素的name属性值是“sale”), 

36 信息系统工程f 2012.9.20 

getElement()方法用于获取元素内容(如:第一个 

attirbute元素的内容是“price”)。 

实 ̄getAttribute0方法的程序思路如下: 

// ̄s]建SAXReader ̄析器实例 

SAXReader reader:new SAXReader(); 

//读取XML文件 

Document doc=reader.read(new File(”config. 

xml”)); 

//获取文档的根节点 

Node root=doc.selectSingleNode(”/root”); 

//获取所有的seller: ̄素 

List list=root.selectNodes(”/root/application[@ 

name=’sale’]/seller”); 

∥获取seller ̄素的name属性值 

for(0bjectobject:list){ 

Element element=(Element)object; 

element.attributeValue(”name”); 

} 

实现getElement0方法的程序和实现getAttribute0方 

法的程序类似。使用方法getText0替换上面程序代码中 

的方法attributeValue0,就能实现getElement0方法。 

三、解析大数据量XML文件 

下面是存储了大量商品信息的SuperMarketA.xm1。 

<?xml version=”1.0”encoding=”gb23 1 2”?> 

<SuperMarketA> 

<coffee> 

<price>69元</price> 

<brand>雀巢96+4杯咖啡促销装</brand> 

<weight>1 300g</weight> 

</coffee> 

<coffee> 

<price>36.9兀</price> 

<brand>麦斯威尔条装咖啡特浓</brand> 

<weight>494g</weight> 

</coffee> 

<milk> 

<price>29.9元</price> 

<brnad>蒙牛纯牛奶(整箱)</brnad> 

<speciifcations>485ml 8袋</speciifcations> 

sYs  .! 旦 塞壁 > 

</milk> 

<milk> 

<price>33元</price> 

<brand>光明利乐枕优+纯牛奶</brand> 

<speciifcations>23 1ml 12袋</speciifcations> 

</milk> 

<SuperMarketA> 

以解析SuperMarketA.xml文件为例,信息系统在解 

析XML文件时,需要按照商品类别,把不同的商品信 

息分别存储到不同的文件里面。也就是,当第一次解 

析到商品标记(如:<coffee>、<milk>等)时,创建以 

商品标记为名称的文本文件(如:coffee.txt、milk.txt 

等),然后把解析出来的商品信息(如: “69元”、 

“雀巢96+4杯咖啡促销装”、“1300g”等)存储到相 

应的文本文件中。 

本文采用SAX方式解析大数据量的XML文件。 

SAX方式的工作原理是:解析器顺序扫描XML文件, 

当扫描到一个标记时,就会产生一个事件,由事件处理 

器调用相应的方法进行处理,然后解析器继续进行同样 

的扫描,直 ̄IJXML文件结束。因此,SAX方式不会占 

用大量内存,不会造成内存溢出问题。 

SAX方式解析XML文件的过程,通常需要经过 

5个步骤:startDocument,startElement,characters, 

endElement,endDocument。在各个步骤中,可以进行 

逻辑判断、获取元素内容、处理元素内容、存储元素内 

容、输出元素内容等操作。以下是在SAX解析类中使用 

到的5个方法,它们分别对应着这5个步骤。 

(1)startDocument()方法:开始处理文档。 

(2)startElement(String uri,String localName, 

String qName,Attributes atts)方法:开始处理元素。需 

要判断参数qName是哪个层级的开始标记(是<coffee> 

层级的标记?还是<price>层级的标记?),以确定什 

么时候开始获取元素内容。另外,需要创建输出文件 

(如:coffee.txt、milk.txt等)。 

(3)characters(char[1 ch,int start,int length)方 

法:获取元素内容。如果qName是<price>层级的开始标 

记,就获取元素的内容(如:“69元”等)。 

(4)endElement(String uri,String localName, 

String qName)方法:结束处理元素。需要对获取到的 

元素内容进行处理(如:过滤某些内容等),并进行临 

时存储,最后将它们输出到对应的文件中(如:coffee. 

txt、milk.txt等)。这样,内存中存储的元素内容,就 

信息系统工程}2012.9.20 37 

< SYS PRACTICE 系统实践 

会不断地输出到存储设备的文件中,因此不会造成内存 

溢出问题。 

{ 

public static void main(String[]args)throws Exception 

(5)endDocument0方法:结束处理文档。需要进 

行一些必要的处理(如:关闭流等)。 

SAX: ̄式解析大数据量XML文件的程序思路如下: 

//通过继承DefaultHandler ̄来继承SAX事件处理方 

1)通过a曙s参数,传递需要解析的Ⅺ血文件的路径。 

2)通过Dom4jParse.java解析配置文件config.xml, 

获得需要解析的XML文件名(如:SuperMarketA.xml、 

SuperMarketB.xml等)。 

3)使用SAX方式逐一解析XML文件(以解析 

法。 

public class SAXParse extends DefaultHandler{ 

,/开始解析XML文档。 

public void startDocument()throws SAXException{} 

//开始解析元素。 

public void startElement(String uri,String 

localName,String qName,Attributes atts)throws 

SAXException{ 

1)判断qName是否为<coffee> ̄级的开始标记。 

如果是,则进一步判断<coffee>是否是第一次出现。如 

果是,则创建coffee.txt输出文件。 

2) ̄lJ断qName是否为<price>层级的开始标记。 

如果是,则进入characters方法。 

} 

//获取元素内容。 

public void characters(char[】ch,int start,int length) 

{ 

1) ̄lJ断当前是否在解析<price>层级的标记。如 

果是,则获取元素的内容。 

} 

//元素解析完毕。 

public void endElement(String uri,String 

localName,String qName)throws SAXException{ 

1)]lJ断qName是否为<price>层级的结束标记。 

如果是,则对元素内容进行某些处理(如:过滤空格、 

字符转换等),然后临时存储元素内容。 

2)判断qName是否为<coffee>层级的结束标记。 

如果是,则将临时存储的所有元素内容输出到相应的 

文件中(如果是</coffee>,则输出 ̄lJcoffee.txt。如果是</ 

milk>,则输出到milk,txt)。 

) 

//文档解析完毕。 

public void endDocument()throws SAXException{ 

11关闭流。 

} 

//主函数,执行SAXParse解析程序的人口。 

38 信息系统工程l 2012.9.20 

SuperMarketA.xml为例)。 

//创建SAX解析器工厂实例。 

SAXParserFactory spf=SAXParserFactory. 

newlnstance0; 

//使用SAX解析器工厂创建解析器实例。 

SAXParser sp=spf.newSAXParser(); 

//paraml:输出文件的路径。 

//param2:config.xml@的所有<product>的name属 

性值和对应的<attribute>内容。 

SAXParse handler=new SAXParse(param l, 

param2); 

//使用SAXParser ̄析器解析XML文件。 

sp.parse(new File(”SuperMarketA.xml”),handler); 

) 

} 

上面的SAX解析程序将XML文件的解析结果存储 

到了文本文件中。如果对解析结果有不同的需求,那么 

可以在SAX解析程序上进行相应的调整。 

四、结束语 

本文通过创建SAX解析程序,实现了解析大数据量 

的XML文件,最终解决了内存溢出问题。此外,本文 

还引入了配置文件,当XML文件中的标记有变更时, 

只需要更改配置文件中的标记,不会影响到SAX解析程 

序源文件。 髑 

参考文献 

[1】张太彪,曾文华,陈志伟.大型XML文档解析技术的应用与研究 

[7】.厦门大学学报:自然科学版,2009,5,48(3):338-341. 

【2】张迪,朱敏,张凌立.基于sAx的xML解析与应用Ⅱ】.计算机与数 

字工程,2008,225(7):103—106. 

[31.- ̄炎.基ff-SAX ̄XML解析异常处理方法Ⅲ.陕西科技大学学 

报,2009,10,27(5):106—109. 

[4]刘雨潇.基于SAX的XML数据解析技术分析研究卟现代电子 

技术,2010,323(12):55—56,65. 

(作者单位:张二松。中国石油勘探开发研究院西 

北分院;缪红萍、宋梦馨。中国石油勘探开发研究院 

计算机应用技术研究所) 


本文标签: 解析 文件 元素 内存 需要