xml常用四种解析方式优缺点的分析

前端之家收集整理的这篇文章主要介绍了xml常用四种解析方式优缺点的分析前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

最近用得到xml的解析方式,于是就翻了翻自己的笔记同时从网上查找了资料,自己在前人的基础上总结了下,贴出来大家分享下。

首先介绍一下xml语言:

可扩展标记语言 (Extensible Markup Language,XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。

xml的语法:

XML分为两部分:头信息,主体信息

头信息是用来描述XML的一些属性,例如:版本,编码等,还可以提供XML显示的样式,和dtd编写格式。

主体信息中包含的是XML的具体数据。

头信息的语法:

<?xmlversion=”1.0”encoding=”GBK” ?>

其中version是必须加的,而encoding可以不写,则默认编码是ISO8859-1不支持中文

除了这个功能外,头信息还可以进行编写格式的规定,通过dtd或xsd文件

头信息还支持样式表的导入,允许通过样式表控制XML的显示

这样可以使用XML+ CSS完成页面显示,通过这种形式完成MVC中的View层:

优点:代码的安全性很高,可以很容易的替换模板。

缺点:开发成本太高

主体信息就是由三种节点组成的,节点之间存在父与子的关系,注意的点:

一个节点只能有一个父节点,如果没有父节点,该节点称为根节点。

一个节点可以有多个子节点。只有元素节点可以拥有子节点。

元素节点的标记必须成对出现,或直接结束。

特殊字符必须转义。依据字符所处的位置是否对XML格式造成影响来决定是否进行转义

根节点只能有一个

xml常用的四种解析方式:

1)DOM(Document Object Model)

文档对象模型分析方式。以层次结构(类似于树型)来组织节点和信息片段,映射XML文档的结构,允许获取和操作文档的任意部分。是W3C的官方标准。

优点:
1、允许应用程序对数据和结构做出更改。
2、访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。

缺点:
1、通常需要加载整个XML文档来构造层次结构,消耗资源大

2)SAX(Simple API for XML)

流模型中的推模型分析方式。通过事件驱动,每发现一个节点就引发一个事件,通过回调方法完成解析工作,解析XML文档的逻辑需要应用程序完成。

优点:
1、不需要等待所有数据都被处理,分析就能立即开始。
2、只在读取数据时检查数据,不需要保存在内存中。
3、可以在某个条件得到满足时停止解析,不必解析整个文档。
4、效率和性能较高,能解析大于系统内存的文档。

缺点:
1、需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),使用麻烦。
2、单向导航,很难同时访问同一文档的不同部分数据,不支持XPath。

3)JDOM(Java-based Document Object Model)

Java特定的文档对象模型。自身不包含解析器,使用SAX。

优点:
1、使用具体类而不是接口,简化了DOM的API。
2、大量使用了Java集合类,方便了Java开发人员。

缺点:
1、没有较好的灵活性。
2、性能较差。

4)DOM4J(Document Object Model for Java)

简单易用,采用Java集合框架,并完全支持DOM、SAX和JAXP。

优点:
1、大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法
2、支持XPath。
3、有很好的性能

缺点:
1、大量使用了接口,API较为复杂。

下面把四种解析方式的代码贴一下,首先是DOM方式

Java代码
  1. publicclassDOMXml{
  2. staticvoidcreateXML(StringoutputPath){
  3. //建立Document对象
  4. DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();
  5. //创建DocumentBuilder
  6. try{
  7. DocumentBuilderdb=factory.newDocumentBuilder();
  8. //创建Document,建立新的对象
  9. Documentdoc=db.newDocument();
  10. //建立各个节点
  11. //元素节点
  12. Elementallplus=doc.createElement("allplus");
  13. Elementareaplus=doc.createElement("areaplus");
  14. Elementid=doc.createElement("id");
  15. Elementtitle=doc.createElement("title");
  16. //创建文本节点
  17. TextidText=doc.createTextNode("1");
  18. TexttitleText=doc.createTextNode("123");
  19. //配置父子节点的关系
  20. id.appendChild(idText);
  21. title.appendChild(titleText);
  22. areaplus.appendChild(id);
  23. areaplus.appendChild(title);
  24. allplus.appendChild(areaplus);
  25. //allplus是根节点,应该设置为doc的子节点
  26. doc.appendChild(allplus);
  27. //执行保存操作
  28. TransformerFactorytf=TransformerFactory.newInstance();
  29. Transformert=tf.newTransformer();
  30. //包装要保存的doc
  31. DOMSourcesource=newDOMSource(doc);
  32. //设置输出
  33. StreamResultsr=newStreamResult(newFile(outputPath));
  34. //设置输出属性
  35. t.setOutputProperty("encoding","UTF-8");
  36. //t.setOutputProperty("version","1.0");
  37. //输出
  38. t.transform(source,sr);
  39. }catch(DOMExceptione){
  40. //TODOAuto-generatedcatchblock
  41. e.printStackTrace();
  42. }catch(ParserConfigurationExceptione){
  43. catch(Exceptione){
  44. //TODOAuto-generatedcatchblock
  45. e.printStackTrace();
  46. }
  47. }
  48. voidparseXML(StringxmlPath){
  49. /*优点:整个文档树在内存中,便于操作;支持删除修改、重新排列等多种功能
  50. *缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
  51. *使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、cpu)。
  52. *10M文档导致内存溢出
  53. */
  54. //创建Document,形成树型结构
  55. Documentdoc=db.parse(newFile(xmlPath));
  56. //先取得所有的data
  57. NodeListdatas=doc.getElementsByTagName("data");
  58. //循环取得每个data
  59. for(inti=0;i<datas.getLength();i++){
  60. Nodedata=datas.item(i);
  61. //由于直接取得第一个和最后一个不符合要求,因此使用取得全部子节点的方式
  62. NodeListactorInfos=data.getChildNodes();
  63. intj=0;j<actorInfos.getLength();j++){
  64. NodeactorInfo=actorInfos.item(j);
  65. NodeListallChild=actorInfo.getChildNodes();
  66. intt=0;t<allChild.getLength();t++){
  67. //判断节点
  68. Nodechild=allChild.item(t);
  69. if(child.getNodeType()==Node.ELEMENT_NODE){
  70. if(child.getNodeName().equals("id")){
  71. //判断是否有孩子节点,然后再取值
  72. if(child.hasChildNodes()){
  73. System.out.println(child.getFirstChild().getNodeValue());
  74. }
  75. }
  76. if(child.getNodeName().equals("name")){
  77. if(child.hasChildNodes()){
  78. System.out.println(child.getFirstChild().getNodeValue());
  79. }
  80. }
  81. }
  82. }
  83. }
  84. }
  85. }catch(SAXExceptione){
  86. catch(IOExceptione){
  87. //TODOAuto-generatedcatchblock
  88. e.printStackTrace();
  89. }
  90. }
  91. voidmain(String[]args){
  92. parseXML("D:/actor_info.xml");
  93. createXML("d:/fxb.xml");
  94. }

SAX解析方式

Java代码 classSAXXmlextendsDefaultHandler{
  • privateList<Book>books=null;
  • privateBookbook=privateStringpreTag=null;//作用是记录解析时的上一个节点名称
  • publicList<Book>getBooks(InputStreamxmlStream)throwsException{
  • SAXParserFactoryfactory=SAXParserFactory.newInstance();
  • SAXParserparser=factory.newSAXParser();
  • SAXXmlhandler=newSAXXml();
  • parser.parse(xmlStream,handler);
  • returnhandler.getBooks();
  • }
  • publicList<Book>getBooks(){
  • returnbooks;
  • }
  • @Override
  • voidstartDocument()throwsSAXException{
  • books=newArrayList<Book>();
  • }
  • voidstartElement(Stringuri,StringlocalName,StringqName,
  • Attributesattributes)throwsSAXException{
  • if("book".equals(qName)){
  • book=newBook();
  • book.setId(Integer.parseInt(attributes.getValue(0)));
  • }
  • preTag=qName;//将正在解析的节点名称赋给preTag
  • }
  • voidendElement(Stringuri,StringqName)
  • if("book".equals(qName)){
  • books.add(book);
  • book=null;
  • }
  • preTag=null;
  • /**
  • *当解析结束时置为空。这里很重要,例如,当图中画3的位置结束后,会调用这个方法
  • *,如果这里不把preTag置为null,根据startElement(....)方法,preTag的值还是book,当文档顺序读到图
  • *中标记4的位置时,会执行characters(char[]ch,intstart,int
  • *length)这个方法,而characters(....)方
  • *法判断preTag!=null,会执行if判断的代码,这样就会把空值赋值给book,这不是我们想要的。
  • */
  • }
  • voidcharacters(char[]ch,intstart,85)">intlength)
  • if(preTag!=null){
  • Stringcontent=newString(ch,start,length);
  • if("name".equals(preTag)){
  • book.setName(content);
  • }elseif("price".equals(preTag)){
  • book.setPrice(Float.parseFloat(content));
  • }
  • }
  • }
  • voidmain(Stringargs[]){
  • SAXXmlhandler=newSAXXml();
  • //定义SUN自带解析对象
  • SAXParserparser;
  • try{
  • parser=SAXParserFactory.newInstance().newSAXParser();
  • parser.parse(newFile("D:/book.xml"),handler);
  • }//TODOAuto-generatedcatchblock
  • e.printStackTrace();
  • }
  • List<Book>books=handler.getBooks();
  • for(Bookbook:books){
  • System.out.println(book.toString());
  • }
  • }
  • JDOM解析方式

    Java代码 classJDOMXml{
  • //先建立Document对象
  • Documentdoc=newDocument();
  • //建立元素节点
  • Elementallplus=newElement("allplus");
  • try{
  • //建立多个Element
  • Elementareaplus=newElement("areaplus");
  • Elementid=newElement("id");
  • Elementtitle=newElement("title");
  • //设置节点内容
  • id.addContent("id");
  • title.addContent("title");
  • //设置父子节点关系
  • areaplus.addContent(id);
  • areaplus.addContent(title);
  • allplus.addContent(areaplus);
  • //设置根节点
  • doc.setRootElement(allplus);
  • //使用IO流操作
  • FileWriterwriter=newFileWriter(//定义输出对象
  • XMLOutputteroutputter=newXMLOutputter();
  • //设置编码
  • outputter.setEncoding("UTF-8");
  • //输出
  • outputter.output(doc,writer);
  • writer.close();
  • }voidparseXML(StringxmlPath){
  • /*
  • */
  • //完成解析功能
  • SAXBuilderbuilder=newSAXBuilder();
  • try{
  • Documentdoc=builder.build(//开始解析,取得根节点
  • Elementdata=doc.getRootElement();
  • //取得所有的areaplus
  • List<Element>actorInfos=data.getChildren("actor_info");
  • if(actorInfos!=null&&actorInfos.size()>0){
  • for(ElementactorInfo:actorInfos){
  • Elementid=actorInfo.getChild("id");
  • Elementname=actorInfo.getChild("name");
  • System.out.println(id.getTextTrim()+"---"+name.getTextTrim());
  • }
  • }
  • }catch(JDOMExceptione){
  • e.printStackTrace();
  • }catch(IOExceptione){
  • e.printStackTrace();
  • }
  • }
  • voidmain(String[]args){
  • parseXML("D:/actor_info.xml");
  • createXML("d:/fdfdsf.xml");
  • }
  • DOM4J解析方式

    Java代码 packagecom.fxb.test;
  • importjava.io.File;
  • importjava.io.FileWriter;
  • importjava.io.IOException;
  • importjava.io.Writer;
  • importjava.util.Iterator;
  • importorg.dom4j.Document;
  • importorg.dom4j.DocumentException;
  • importorg.dom4j.DocumentHelper;
  • importorg.dom4j.Element;
  • importorg.dom4j.io.SAXReader;
  • importorg.dom4j.io.XMLWriter;
  • *
  • *@authorhongliang.dinghlDom4j生成XML文档与解析XML文档
  • */
  • classDOM4JXml{
  • voidcreateXml(StringfileName){
  • Documentdocument=DocumentHelper.createDocument();
  • Elementemployees=document.addElement("data");
  • Elementemployee=employees.addElement("actor_info");
  • Elementid=employee.addElement("id");
  • id.setText("1");
  • Elementname=employee.addElement("name");
  • name.setText("你好");
  • Elementmessage=employee.addElement("message");
  • message.setText("你好吗");
  • Elementpic=employee.addElement("pic");
  • pic.setText("123");
  • Elementsex=employee.addElement("sex");
  • pic.setText("男");
  • Elementbirthday=employee.addElement("birthday");
  • pic.setText("19881212");
  • try{
  • WriterfileWriter=newFileWriter(fileName);
  • XMLWriterxmlWriter=newXMLWriter(fileWriter);
  • xmlWriter.write(document);
  • xmlWriter.close();
  • }catch(IOExceptione){
  • System.out.println(e.getMessage());
  • }
  • }
  • voidparserXml(StringfileName){
  • FileinputXml=newFile(fileName);
  • SAXReadersaxReader=newSAXReader();
  • try{
  • Documentdocument=saxReader.read(inputXml);
  • Elementdata=document.getRootElement();
  • for(Iteratori=data.elementIterator();i.hasNext();){
  • ElementactorInfo=(Element)i.next();
  • //System.out.println(employee.getName()+"->"+employee.getText());
  • for(Iteratorj=actorInfo.elementIterator();j.hasNext();){
  • Elementchild=(Element)j.next();
  • System.out.println(child.getName()+":"+child.getText());
  • }
  • System.out.println("=================");
  • }
  • }catch(DocumentExceptione){
  • System.out.println(e.getMessage());
  • }
  • }
  • voidmain(Stringargs[]){
  • DOM4JXmldom=newDOM4JXml();
  • //dom.parserXml("d:/actor_info.xml");
  • dom.createXml("d:/fxb.xml");
  • }
  • }
  • 猜你在找的XML相关文章