加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 05:50:10 所属栏目:百科 来源:网络整理
导读:最近用得到xml的解析方式,于是就翻了翻自己的笔记同时从网上查找了资料,自己在前人的基础上总结了下,贴出来大家分享下。 首先介绍一下xml语言: 可扩展标记语言 (Extensible Markup Language,XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来

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

首先介绍一下xml语言:

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

xml的语法:

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

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

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

头信息的语法:

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

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

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

头信息还支持样式表的导入,允许通过样式表控制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代码

  1. classSAXXmlextendsDefaultHandler{

  2. privateList<Book>books=null;

  3. privateBookbook=privateStringpreTag=null;//作用是记录解析时的上一个节点名称

  4. publicList<Book>getBooks(InputStreamxmlStream)throwsException{

  5. SAXParserFactoryfactory=SAXParserFactory.newInstance();

  6. SAXParserparser=factory.newSAXParser();

  7. SAXXmlhandler=newSAXXml();

  8. parser.parse(xmlStream,handler);

  9. returnhandler.getBooks();

  10. }

  11. publicList<Book>getBooks(){

  12. returnbooks;

  13. }

  14. @Override

  15. voidstartDocument()throwsSAXException{

  16. books=newArrayList<Book>();

  17. }

  18. voidstartElement(Stringuri,StringlocalName,StringqName,

  19. Attributesattributes)throwsSAXException{

  20. if("book".equals(qName)){

  21. book=newBook();

  22. book.setId(Integer.parseInt(attributes.getValue(0)));

  23. }

  24. preTag=qName;//将正在解析的节点名称赋给preTag

  25. }

  26. voidendElement(Stringuri,StringqName)

  27. if("book".equals(qName)){

  28. books.add(book);

  29. book=null;

  30. }

  31. preTag=null;

  32. /**

  33. *当解析结束时置为空。这里很重要,例如,当图中画3的位置结束后,会调用这个方法

  34. *,如果这里不把preTag置为null,根据startElement(....)方法,preTag的值还是book,当文档顺序读到图

  35. *中标记4的位置时,会执行characters(char[]ch,intstart,int

  36. *length)这个方法,而characters(....)方

  37. *法判断preTag!=null,会执行if判断的代码,这样就会把空值赋值给book,这不是我们想要的。

  38. */

  39. }

  40. voidcharacters(char[]ch,intstart,85);font-weight: bold">intlength)

  41. if(preTag!=null){

  42. Stringcontent=newString(ch,start,length);

  43. if("name".equals(preTag)){

  44. book.setName(content);

  45. }elseif("price".equals(preTag)){

  46. book.setPrice(Float.parseFloat(content));

  47. }

  48. }

  49. }

  50. voidmain(Stringargs[]){

  51. SAXXmlhandler=newSAXXml();

  52. //定义SUN自带解析对象

  53. SAXParserparser;

  54. try{

  55. parser=SAXParserFactory.newInstance().newSAXParser();

  56. parser.parse(newFile("D:/book.xml"),handler);

  57. }//TODOAuto-generatedcatchblock

  58. e.printStackTrace();

  59. }

  60. List<Book>books=handler.getBooks();

  61. for(Bookbook:books){

  62. System.out.println(book.toString());

  63. }

  64. }

JDOM解析方式

Java代码

  1. classJDOMXml{

  2. //先建立Document对象

  3. Documentdoc=newDocument();

  4. //建立元素节点

  5. Elementallplus=newElement("allplus");

  6. try{

  7. //建立多个Element

  8. Elementareaplus=newElement("areaplus");

  9. Elementid=newElement("id");

  10. Elementtitle=newElement("title");

  11. //设置节点内容

  12. id.addContent("id");

  13. title.addContent("title");

  14. //设置父子节点关系

  15. areaplus.addContent(id);

  16. areaplus.addContent(title);

  17. allplus.addContent(areaplus);

  18. //设置根节点

  19. doc.setRootElement(allplus);

  20. //使用IO流操作

  21. FileWriterwriter=newFileWriter(//定义输出对象

  22. XMLOutputteroutputter=newXMLOutputter();

  23. //设置编码

  24. outputter.setEncoding("UTF-8");

  25. //输出

  26. outputter.output(doc,writer);

  27. writer.close();

  28. }voidparseXML(StringxmlPath){

  29. /*

  30. */

  31. //完成解析功能。

  32. SAXBuilderbuilder=newSAXBuilder();

  33. try{

  34. Documentdoc=builder.build(//开始解析,取得根节点

  35. Elementdata=doc.getRootElement();

  36. //取得所有的areaplus

  37. List<Element>actorInfos=data.getChildren("actor_info");

  38. if(actorInfos!=null&&actorInfos.size()>0){

  39. for(ElementactorInfo:actorInfos){

  40. Elementid=actorInfo.getChild("id");

  41. Elementname=actorInfo.getChild("name");

  42. System.out.println(id.getTextTrim()+"---"+name.getTextTrim());

  43. }

  44. }

  45. }catch(JDOMExceptione){

  46. e.printStackTrace();

  47. }catch(IOExceptione){

  48. e.printStackTrace();

  49. }

  50. }

  51. voidmain(String[]args){

  52. parseXML("D:/actor_info.xml");

  53. createXML("d:/fdfdsf.xml");

  54. }

DOM4J解析方式

Java代码

  1. packagecom.fxb.test;

  2. importjava.io.File;

  3. importjava.io.FileWriter;

  4. importjava.io.IOException;

  5. importjava.io.Writer;

  6. importjava.util.Iterator;

  7. importorg.dom4j.Document;

  8. importorg.dom4j.DocumentException;

  9. importorg.dom4j.DocumentHelper;

  10. importorg.dom4j.Element;

  11. importorg.dom4j.io.SAXReader;

  12. importorg.dom4j.io.XMLWriter;

  13. *

  14. *@authorhongliang.dinghlDom4j生成XML文档与解析XML文档

  15. */

  16. classDOM4JXml{

  17. voidcreateXml(StringfileName){

  18. Documentdocument=DocumentHelper.createDocument();

  19. Elementemployees=document.addElement("data");

  20. Elementemployee=employees.addElement("actor_info");

  21. Elementid=employee.addElement("id");

  22. id.setText("1");

  23. Elementname=employee.addElement("name");

  24. name.setText("你好");

  25. Elementmessage=employee.addElement("message");

  26. message.setText("你好吗");

  27. Elementpic=employee.addElement("pic");

  28. pic.setText("123");

  29. Elementsex=employee.addElement("sex");

  30. pic.setText("男");

  31. Elementbirthday=employee.addElement("birthday");

  32. pic.setText("19881212");

  33. try{

  34. WriterfileWriter=newFileWriter(fileName);

  35. XMLWriterxmlWriter=newXMLWriter(fileWriter);

  36. xmlWriter.write(document);

  37. xmlWriter.close();

  38. }catch(IOExceptione){

  39. System.out.println(e.getMessage());

  40. }

  41. }

  42. voidparserXml(StringfileName){

  43. FileinputXml=newFile(fileName);

  44. SAXReadersaxReader=newSAXReader();

  45. try{

  46. Documentdocument=saxReader.read(inputXml);

  47. Elementdata=document.getRootElement();

  48. for(Iteratori=data.elementIterator();i.hasNext();){

  49. ElementactorInfo=(Element)i.next();

  50. //System.out.println(employee.getName()+"->"+employee.getText());

  51. for(Iteratorj=actorInfo.elementIterator();j.hasNext();){

  52. Elementchild=(Element)j.next();

  53. System.out.println(child.getName()+":"+child.getText());

  54. }

  55. System.out.println("=================");

  56. }

  57. }catch(DocumentExceptione){

  58. System.out.println(e.getMessage());

  59. }

  60. }

  61. voidmain(Stringargs[]){

  62. DOM4JXmldom=newDOM4JXml();

  63. //dom.parserXml("d:/actor_info.xml");

  64. dom.createXml("d:/fxb.xml");

  65. }

  66. }

引用:http://lewis-fxb.iteye.com/blog/1243298

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读