微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

两种处理XML方式的比较---DOM and SAX


一、DOM文档对象模式
1.DOM特点:
以树型结构访问XML文档。一棵DOM树包含全部元素节点和文本节点。可以前后遍历树中的每一个节点。
整个文档树在内存中,便于操作;支持删除修改、重新排列等多种功能
将整个文档调入内存(包括无用的节点),浪费时间和空间。
一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、cpu)情况下使用。


2.DOM树与节点
XML文档被解析成树型结构。
树由节点组成。共有12种不同的节点。
节点可以包含其他节点(依赖于节点的类型)。
父节点包含子节点。叶子节点没有子节点。


3.节点类型
Documentnode包含:一个Element节点。一个或多个处理指令节点。
DocumentFragmentnode
Elementnode包含:其他Element节点。若干个Text节点。若干个Attribute节点。
Attributenode包含:一个Text节点。
Textnode
Commentnode
Processinginstructionnode
Documenttypenode
Entitynode
Entityreferencenode
CDATAsectionnode
Notationnode


二、SAX基于事件处理模式
解析器向一个事件处理程序发送事件,比如元素开始和元素结束,而事件处理器则处理该信息。
然后应用程序本身就能够处理该数据。原始的文档仍然保留完好无损。

<![CDATA[##################SAX处理器(遍历XML)###########################]]>
importjava.io.IOException;

importjavax.xml.parsers.ParserConfigurationException;
importjavax.xml.parsers.SAXParser;
importjavax.xml.parsers.SAXParserFactory;

importorg.xml.sax.Attributes;
importorg.xml.sax.SAXException;
importorg.xml.sax.SAXParseException;
importorg.xml.sax.helpers.DefaultHandler;

publicclasstestSAXParser{
/**基于SAX方式解析XML文档*/
publicstaticvoidmain(String[]args)
throwsSAXException,ParserConfigurationException,IOException{
SAXParserFactoryfactory=SAXParserFactory.newInstance();//创建SAX解析器工厂
factory.setValidating(true);//error方法生效
SAXParserparser=factory.newSAXParser();//生成一个具体的SAX解析器
parser.parse("src/file/student.xml",newXMLreader());//开始解析
}}

classXMLreaderextendsDefaultHandler{
//只需覆盖我们感兴趣的方法
privateintcounter=0;//定义一个计数器,保存XML文档触发事件的次数

@Override//文档开始事件触发
publicvoidstartDocument()throwsSAXException{
counter++;
System.out.println(counter+".解析XML文件开始...");}

@Override//文档结束事件触发
publicvoidendDocument()throwsSAXException{
counter++;
System.out.println("\r\n"+counter+".解析XML文件结束...");}

@Override//元素开始事件触发
publicvoidstartElement(Stringuri,StringlocalName,StringqName,
Attributesatts)throwsSAXException{
counter++;
System.out.print(counter+".<"+qName);
for(inti=0;i<atts.getLength();i++){//读取标志的所有属性
System.out.print(""+atts.getLocalName(i)+"="+atts.getValue(i));
}System.out.print(">");}

@Override//元素结束事件触发
publicvoidendElement(Stringuri,StringqName)throwsSAXException{
counter++;
System.out.print(counter+".</"+qName+">");}

@Override//文本事件触发打印时尽量不要换行,否则很难看
publicvoidcharacters(char[]ch,intstart,intlength)throwsSAXException{
counter++;
Stringtext=newString(ch,start,length);//当前元素的文本值
System.out.print(counter+".Text="+text);}

@Override//这是可恢复错误。需在SAXParserFactory设置有效性错误才能生效
publicvoiderror(SAXParseExceptione)throwsSAXException{
System.out.println("xml文档有效性错误"+e);}

@Override//严重错误
publicvoidfatalError(SAXParseExceptione)throwsSAXException{
System.out.println("xml文档严重的有效性错误"+e);}
}
<![CDATA[##################SAX处理器(遍历XML)结束###########################]]>

三、DOM
<![CDATA[#########################DOM遍历方式###########################]]>
importjava.io.File;
importjava.io.IOException;

importjavax.xml.parsers.DocumentBuilder;
importjavax.xml.parsers.DocumentBuilderFactory;
importjavax.xml.parsers.ParserConfigurationException;

importorg.w3c.dom.Attr;
importorg.w3c.dom.Document;
importorg.w3c.dom.Element;
importorg.w3c.dom.NamednodeMap;
importorg.w3c.dom.Node;
importorg.w3c.dom.NodeList;
importorg.xml.sax.SAXException;

/**基于DOM的解析XML文档*/
publicclasstestDOMParser{
publicstaticvoidmain(String[]args)
throwsParserConfigurationException,SAXException,IOException{
//创建一个DOM解析器工厂
DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();
//从工厂中生成一个DOM解析器;throwsParserConfigurationException
DocumentBuilderbuilder=factory.newDocumentBuilder();
//绑定需要解析的XML文件
FilexmlFile=newFile("src/file/student.xml");//相对地址,相对于这个工程
//开始解析;throwsSAXException,IOException
Documentdocument=builder.parse(xmlFile);
//取出唯一的根元素
ElementrootElement=document.getDocumentElement();
//调用业务方法:遍历根元素
printElement(rootElement);
}

/**遍历元素,包含:子元素、属性、文本内容*/
privatestaticvoidprintElement(Elemente){
//打印出元素的标签
System.out.print("<"+e.getTagName());
//获取开始标签属性
NamednodeMapattMap=e.getAttributes();
//循环遍历所有的属性
for(inti=0;i<attMap.getLength();i++){
Attrattr=(Attr)attMap.item(i);
System.out.print(""+attr.getName()+"=\""+attr.getValue()+"\"");}
System.out.print(">");

//获取当前元素的所有子节点
NodeListnl=e.getChildNodes();
for(intj=0;j<nl.getLength();j++){
Noden=nl.item(j);
if(Node.ELEMENT_NODE==n.getNodeType()){
printElement((Element)n);//递归调用,以遍历下一个元素
}else{
System.out.print(n.getTextContent());
}
}
//打印结束标签
System.out.print("</"+e.getTagName()+">");
}}
<![CDATA[######################DOM遍历完毕##########################]]>

比较DOMSAX


DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML随机访问
优点:1.提供随机定义元素操作,来回移动指针
2.将整个XML文件一次性加载到内存,形成虚的内存树
缺点:1.如果XML文件较大,内存空间占用较大
2.强制将较大的XML文件加载到内存中,有可能损害文件
3.功能通用性

SAX:不同于DOM,SAX是事件驱动型的XML解析方式。它顺序逐行读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问

原文地址:https://www.jb51.cc/xml/300464.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。