精华内容
下载资源
问答
  • Java中的两种XML解析技术DOM和SAX

    千次阅读 2013-03-24 09:47:15
    Java中的两种XML解析技术DOM和SAX 目标文件:D:/meno.xml 王平 男 12月23日 吉林省白山市第八中学 0439-31344532 wangping@sina.com 今天是王平生日 东方雪 女 8月23日 北京海淀区中关村E...

    Java中的两种XML解析技术DOM和SAX



    目标文件:D:/meno.xml

    <memo>
    <note type="birthday">
    	<name>王平</name>
    	<sex>男</sex>
    	<date>12月23日</date>
    	<address>吉林省白山市第八中学</address>
    	<telphone>0439-31344532</telphone>
    	<email>wangping@sina.com</email>
    	<body>今天是王平生日</body>
    </note>
    <note type="shop">
    	<name>东方雪</name>
    	<sex>女</sex>
    	<date>8月23日</date>
    	<address>北京海淀区中关村E世界</address>
    	<telphone>15984561235</telphone>
    	<email>eworld@vip.com</email>
    	<body>今天是东方雪店铺开张的日子</body>
    </note>
    </memo>




    DOM解析

    步骤:

    1.获取factory

    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();

    2.获取builder

    builder = builderFactory.newDocumentBuilder();

    3.解析为Document对象

    Document document = builder.parse(xmlFile);

    import java.io.File;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    public class DomTest {
    	public static void main(String[] args) {
    		File xmlFile = new File("D:\\memo.xml");
    		DocumentBuilder builder = null;
    		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    		try {
    			builder = builderFactory.newDocumentBuilder();
    			Document document = builder.parse(xmlFile);		//解析文件
    			Element root = document.getDocumentElement();	//获得根元素
    			System.out.println("根元素:" + root.getNodeName());
    			NodeList childNodes = root.getChildNodes();		//获得根元素下的子节点
    			for (int i = 0; i < childNodes.getLength(); i++) {	//遍历这些子节点
    				Node node = childNodes.item(i);
    				if("note".equals(node.getNodeName())) {
    					//如果节点的名称为"node",则输出note元素属性type
    					System.out.println("\r\n 找到一篇日记。所属分类:" + node.getAttributes().getNamedItem("type").getNodeValue()+".");
    					NodeList nodeDetail = node.getChildNodes();
    					for(int j = 0; j < nodeDetail.getLength(); j++) 
    					{
    						Node detail = nodeDetail.item(j);
    						if("name".equals(detail.getNodeName()))
    							System.out.println("姓名: " + detail.getTextContent());
    						else if("sex".equals(detail.getNodeName()))
    							System.out.println("性别:" + detail.getTextContent());
    						else if("date".equals(detail.getNodeName())) 
    							System.out.println("日期:" + detail.getTextContent());
    						else if("address:".equals(detail.getNodeName()))
    							System.out.println("居住地址:" + detail.getTextContent());
    						else if("telephone".equals(detail.getNodeName()))
    							System.out.println("电话号码:" + detail.getTextContent());
    						else if("email".equals(detail.getNodeName()))
    							System.out.println("E-mail: " + detail.getTextContent());
    						else if("body".equals(detail.getNodeName()))
    							System.out.println("主题:" + detail.getTextContent());
    							
    					}
    				}
    				
    			}
    			
    		}
    		catch(Exception e) {
    			e.printStackTrace();
    		}
    	}
    }

    SAX解析

    步骤:

    1.获取factory

    SAXParserFactory factory = SAXParserFactory.newInstance();

    2.获取parser

    SAXParser parser = factory.newSAXParser();

    3.开始解析

    parser.parse(xmlFile,new MySaxListener());


    import java.io.File;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    
    public class SaxTest {
    	public static void main(String[] args) {
    		File xmlFile = new File("D:\\memo.xml");
    		SAXParserFactory factory = SAXParserFactory.newInstance();
    		try {
    			SAXParser parser = factory.newSAXParser();
    			parser.parse(xmlFile,new MySaxListener());
    			
    		} catch(Exception e) {
    			e.printStackTrace();
    		}
    	}
    }


    import org.xml.sax.helpers.DefaultHandler;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    
    public class MySaxListener extends DefaultHandler {
    	private String content;
    	
    	public void characters(char[] ch, int start, int length) throws SAXException {
    		content = new String(ch, start, length);
    	}
    	
    	public void endElement(String uri, String localName, String qName) throws SAXException {	
    		if("name".equals(qName)) {
    			System.out.println("姓名:" + content);
    		} else if("sex".equals(qName)) {
    			System.out.println("性别:" + content);
    		}else if("date".equals(qName)) {
    			System.out.println("日期:" + content);
    		}else if("address".equals(qName)) {
    			System.out.println("居住地址:" + content);
    		}else if("telephone".equals(qName)) {
    			System.out.println("电话号码:" + content);
    		}else if("email".equals(qName)) {
    			System.out.println("电子邮件:" + content);
    		}else if("body".equals(qName)) {
    			System.out.println("主题:" + content);
    		}
    	}
    	
    	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    		if("note".equals(qName)) {
    			System.out.println("下面是一个关于SAX的解析方式:");
    			System.out.println("\r\n找到一篇文章.所属分类:" + attributes.getValue("type") + ".");
    		}
    	}
    }


    解析结果







    展开全文
  • XML解析技术

    千次阅读 2012-10-19 15:03:34
    XML解析技术 1、XML解析技术概述: (1)XML解析方式分为两种:dom和sax dom:(Document Object Model, 即文档对象模型) 是 W3C 组织推荐的处理 XML  的一种方式。 sax: (Simple API for XML) 不是...
    XML解析技术


    1、XML解析技术概述:
    (1)XML解析方式分为两种:dom和sax
    dom:(Document Object Model, 即文档对象模型) 是 W3C 组织推荐的处理 XML
     的一种方式。
    sax: (Simple API for XML) 不是官方标准,但它是 XML 社区事实上的标准,几
    乎所有的 XML 解析器都支持它。

    (2)XML解析器:
    Crimson、Xerces 、Aelfred2

    (3)XML解析开发包:
    Jaxp、Jdom、dom4j

    2、jaxp的介绍:
         JAXP 开发包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及 其子包组成.
         在 javax.xml.parsers 包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的 DOM 或 SAX 的解析器对象。

    3、获得JAXP中的DOM解析器的步骤:

    (1)调用 DocumentBuilderFactory.newInstance() 方法得到创建 DOM 解析器的工厂。

    (2)调用工厂对象的 newDocumentBuilder方法得到 DOM 解析器对象。

    (3)调用 DOM 解析器对象的 parse() 方法解析 XML 文档,得到代表整个文档的 Document 对象,进行可以利用DOM特性对整个XML文档进行操作了。

    4、DOM编程:
    DOM模型(document object model):

    (1)DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。
    (2)在dom中,节点之间关系如下:
        位于一个节点之上的节点是该节点的父节点(parent)
        一个节点之下的节点是该节点的子节点(children) 
        同一层次,具有相同父节点的节点是兄弟节点(sibling) 
        一个节点的下一个层次的节点集合是节点后代(descendant)
        父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor) 
    5、Node对象:
        Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。

    6、更新XML文档:
    (1)javax.xml.transform包中的Transformer类用于把代表XML文件的Document对
    象转换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。利
    用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。

    (2)Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过:
    <1>javax.xml.transform.dom.DOMSource类来关联要转换的document对象。 
    <2>用javax.xml.transform.stream.StreamResult 对象来表示数据的目的地。

    (3) Transformer对象通过TransformerFactory获得。

    7、用SAX方式解析XML文档:
    使用SAXParserFactory创建SAX解析工厂
    SAXParserFactory spf = SAXParserFactory.newInstance();

    通过SAX解析工厂得到解析器对象
    SAXParser sp = spf.newSAXParser();

    通过解析器对象得到一个XML的读取器
    XMLReader xmlReader = sp.getXMLReader();

    设置读取器的事件处理器
    xmlReader.setContentHandler(new BookParserHandler());

    解析xml文件
    xmlReader.parse("book.xml");


    8、DOM4J解析XML文档:
         Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM开发的。与JDOM不同的是,dom4j使用接口和抽象的人分离出来而后独立基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。 

         Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。
         使用Dom4j开发,需下载dom4j相应的jar文件。




    展开全文
  • Java中四种XML解析技术

    千次阅读 2012-04-27 10:18:53
    在这篇文章中,我对这四主流方案做一个不完全评测,仅仅针对遍历 XML 这块来测试,因为遍历 XML 是工作中使用最多的(至少我认为)。  预 备  测试环境:  计算机硬件软件环境:AMD 毒龙1.4G OC ...

    在平时工作中,难免会遇到把 XML 作为数据存储格式。面对目前种类繁多的解决方案,哪个最适合我们呢?在这篇文章中,我对这四种主流方案做一个不完全评测,仅仅针对遍历 XML 这块来测试,因为遍历 XML 是工作中使用最多的(至少我认为)。

      预 备

      测试环境:

      计算机硬件软件环境:AMD 毒龙1.4G OC 1.5G、256M DDR333、Windows2000 Server SP4、Sun JDK 1.4.1+Eclipse 2.1+Resin 2.1.8,在 Debug 模式下测试。

      XML 文件格式如下:

      <?xml version="1.0" encoding="GB2312"?>
      <RESULT>
      <VALUE>
      <NO>A1234</NO>
      <ADDR>四川省XX县XX镇XX路X段XX号</ADDR>
      </VALUE>
      <VALUE>
      <NO>B1234</NO>
      <ADDR>四川省XX市XX乡XX村XX组</ADDR>
      </VALUE>
      </RESULT>

      测试方法:

      采用 JSP 端调用Bean(至于为什么采用JSP来调用,请参考:http://blog.csdn.net/rosen/archive/2004/10/15/138324.aspx),让每一种方案分别解析10K、100K、1000K、10000K的 XML 文件,计算其消耗时间(单位:毫秒)。

      JSP 文件:

      <%@ page contentType="text/html; charset=gb2312" %>
      <%@ page import="com.test.*"%>

      <html>
      <body>
      <%
      String args[]={""};
      MyXMLReader.main(args);
      %>
      </body>
      </html>

      测 试

      1:首先出场的是 DOM(JAXP Crimson 解析器)

      DOM 是用与平台和语言无关的方式表示 XML 文档的官方 W3C 标准。DOM 是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而 DOM 被认为是基于树或基于对象的。DOM 以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像 SAX 那样是一次性的处理。DOM 使用起来也要简单得多。

      另一方面,对于特别大的文档,解析和加载整个文档可能很慢且很耗资源,因此使用其他手段来处理这样的数据会更好。这些基于事件的模型,比如 SAX。

      Bean文件:

      package com.test;

      import java.io.*;
      import java.util.*;
      import org.w3c.dom.*;
      import javax.xml.parsers.*;

      public class MyXMLReader{

      public static void main(String arge[]){
      long lasting =System.currentTimeMillis();
      try{
       File f=new File("data_10k.xml");
       DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
       DocumentBuilder builder=factory.newDocumentBuilder();
       Document doc = builder.parse(f);
       NodeList nl = doc.getElementsByTagName("VALUE");
       for (int i=0;i<nl.getLength();i++){
        System.out.print("车牌号码:" + doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue());
        System.out.println(" 车主地址:" + doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue());
      }
      }catch(Exception e){
       e.printStackTrace();
      }
      System.out.println("运行时间:"+(System.currentTimeMillis() - lasting)+" 毫秒");
      }
      }


      10k消耗时间:265 203 219 172
      100k消耗时间:9172 9016 8891 9000
      1000k消耗时间:691719 675407 708375 739656
      10000k消耗时间:OutOfMemoryError 



      2 接着是 SAX

      这种处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX 还比它的替代者 DOM 快许多。

       选择 DOM 还是选择 SAX ?

      对于需要自己编写代码来处理 XML 文档的开发人员来说,选择 DOM 还是 SAX 解析模型是一个非常重要的设计决策。

      DOM 采用建立树形结构的方式访问 XML 文档,而 SAX 采用的事件模型。

      DOM 解析器把 XML 文档转化为一个包含其内容的树,并可以对树进行遍历。用 DOM 解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用 DOM 解析器的时候需要处理整个 XML 文档,所以对性能和内存的要求比较高,尤其是遇到很大的 XML 文件的时候。由于它的遍历能力,DOM 解析器常用于 XML 文档需要频繁的改变的服务中。

      SAX 解析器采用了基于事件的模型,它在解析 XML 文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX 这种扩展能力得到了更好的体现。但用 SAX 解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。

      Bean文件:

      package com.test;
      import org.xml.sax.*;
      import org.xml.sax.helpers.*;
      import javax.xml.parsers.*;

      public class MyXMLReader extends DefaultHandler {

      java.util.Stack tags = new java.util.Stack();

      public MyXMLReader() {
      super();
      }

      public static void main(String args[]) {
      long lasting = System.currentTimeMillis();
      try {
       SAXParserFactory sf = SAXParserFactory.newInstance();
       SAXParser sp = sf.newSAXParser();
       MyXMLReader reader = new MyXMLReader();
       sp.parse(new InputSource("data_10k.xml"), reader);
      } catch (Exception e) {
       e.printStackTrace();
      }
      System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) + " 毫秒");
      }

      public void characters(char ch[], int start, int length) throws SAXException {
      String tag = (String) tags.peek();
      if (tag.equals("NO")) {
       System.out.print("车牌号码:" + new String(ch, start, length));
      }
      if (tag.equals("ADDR")) {
      System.out.println(" 地址:" + new String(ch, start, length));
      }
      }

      public void startElement(
      String uri,
      String localName,
      String qName,
      Attributes attrs) {
      tags.push(qName);
      }
      }

      10k消耗时间:110 47 109 78
      100k消耗时间:344 406 375 422
      1000k消耗时间:3234 3281 3688 3312
      10000k消耗时间:32578 34313 31797 31890 30328

      3 然后是 JDOM http://www.jdom.org/

      JDOM 的目的是成为 Java 特定文档模型,它简化与 XML 的交互并且比使用 DOM 实现更快。由于是第一个 Java 特定模型,JDOM 一直得到大力推广和促进。正在考虑通过“Java 规范请求 JSR-102”将它最终用作“Java 标准扩展”。从 2000 年初就已经开始了 JDOM 开发。

      JDOM 与 DOM 主要有两方面不同。首先,JDOM 仅使用具体类而不使用接口。这在某些方面简化了 API,但是也限制了灵活性。第二,API 大量使用了 Collections 类,简化了那些已经熟悉这些类的 Java 开发者的使用。

      JDOM 文档声明其目的是“使用 20%(或更少)的精力解决 80%(或更多)Java/XML 问题”(根据学习曲线假定为 20%)。JDOM 对于大多数 Java/XML 应用程序来说当然是有用的,并且大多数开发者发现 API 比 DOM 容易理解得多。JDOM 还包括对程序行为的相当广泛检查以防止用户做任何在 XML 中无意义的事。然而,它仍需要您充分理解 XML 以便做一些超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习 DOM 或 JDOM 接口都更有意义的工作。

      JDOM 自身不包含解析器。它通常使用 SAX2 解析器来解析和验证输入 XML 文档(尽管它还可以将以前构造的 DOM 表示作为输入)。它包含一些转换器以将 JDOM 表示输出成 SAX2 事件流、DOM 模型或 XML 文本文档。JDOM 是在 Apache 许可证变体下发布的开放源码。

      Bean文件:

      package com.test;

      import java.io.*;
      import java.util.*;
      import org.jdom.*;
      import org.jdom.input.*;

      public class MyXMLReader {

      public static void main(String arge[]) {
      long lasting = System.currentTimeMillis();
      try {
       SAXBuilder builder = new SAXBuilder();
       Document doc = builder.build(new File("data_10k.xml"));
       Element foo = doc.getRootElement();
       List allChildren = foo.getChildren();
       for(int i=0;i<allChildren.size();i++) {
        System.out.print("车牌号码:" + ((Element)allChildren.get(i)).getChild("NO").getText());
        System.out.println(" 车主地址:" + ((Element)allChildren.get(i)).getChild("ADDR").getText());
       }
      } catch (Exception e) {
       e.printStackTrace();
      }
      System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) + " 毫秒");
      }
      }

      10k消耗时间:125 62 187 94
      100k消耗时间:704 625 640 766
      1000k消耗时间:27984 30750 27859 30656
      10000k消耗时间:OutOfMemoryError

      4 最后是 DOM4J http://dom4j.sourceforge.net/

      虽然 DOM4J 代表了完全独立的开发结果,但最初,它是 JDOM 的一种智能分支。它合并了许多超出基本 XML 文档表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过 DOM4J API 和标准 DOM 接口具有并行访问功能。从 2000 下半年开始,它就一直处于开发之中。

      为支持所有这些功能,DOM4J 使用接口和抽象基本类方法。DOM4J 大量使用了 API 中的 Collections 类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然 DOM4J 付出了更复杂的 API 的代价,但是它提供了比 JDOM 大得多的灵活性。

      在添加灵活性、XPath 集成和对大文档处理的目标时,DOM4J 的目标与 JDOM 是一样的:针对 Java 开发者的易用性和直观操作。它还致力于成为比 JDOM 更完整的解决方案,实现在本质上处理所有 Java/XML 问题的目标。在完成该目标时,它比 JDOM 更少强调防止不正确的应用程序行为。

      DOM4J 是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。

      Bean文件:

      package com.test;

      import java.io.*;
      import java.util.*;
      import org.dom4j.*;
      import org.dom4j.io.*;

      public class MyXMLReader {

      public static void main(String arge[]) {
      long lasting = System.currentTimeMillis();
      try {
       File f = new File("data_10k.xml");
       SAXReader reader = new SAXReader();
       Document doc = reader.read(f);
       Element root = doc.getRootElement();
       Element foo;
       for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) {
        foo = (Element) i.next();
        System.out.print("车牌号码:" + foo.elementText("NO"));
        System.out.println(" 车主地址:" + foo.elementText("ADDR"));
       }
      } catch (Exception e) {
       e.printStackTrace();
      }
      System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) + " 毫秒");
      }
      }

      10k消耗时间:109 78 109 31
      100k消耗时间:297 359 172 312
      1000k消耗时间:2281 2359 2344 2469
      10000k消耗时间:20938 19922 20031 21078

      JDOM 和 DOM 在性能测试时表现不佳,在测试 10M 文档时内存溢出。在小文档情况下还值得考虑使用 DOM 和 JDOM。虽然 JDOM 的开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。另外,DOM 仍是一个非常好的选择。DOM 实现广泛应用于多种编程语言。它还是许多其它与 XML 相关的标准的基础,因为它正式获得 W3C 推荐(与基于非标准的 Java 模型相对),所以在某些类型的项目中可能也需要它(如在 JavaScript 中使用 DOM)。

      SAX表现较好,这要依赖于它特定的解析方式。一个 SAX 检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。

      无疑,DOM4J是这场测试的获胜者,目前许多开源项目中大量采用 DOM4J,例如大名鼎鼎的 Hibernate 也用 DOM4J 来读取 XML 配置文件。如果不考虑可移植性,那就采用DOM4J吧!


    展开全文
  • 常用 XML 解析技术

    千次阅读 2018-04-12 10:44:09
    现在的软件项目都不是独立的一个项目,都是多系统协调工作。这样的话就涉及到系统间的通讯,通讯就会跟报文传输...Java 是一个开源的语言,本场 Chat 将给大家介绍一下常用的 XML 解析框架及特点。 主要内容: XML ...

    现在的软件项目都不是独立的一个项目,都是多系统协调工作。这样的话就涉及到系统间的通讯,通讯就会跟报文传输挂上关系。系统间使用怎样的报文格式进行通讯呢?有的使用固定长度格式报文;有的使用变长格式报文;有的使用 XML格式报告。本场 Chat 主要和大家分享一下 XML 格式报文的解析。Java 是一个开源的语言,本场 Chat 将给大家介绍一下常用的 XML 解析框架及特点。

    主要内容:

    • XML 的简介及一些常见概念 ;
    • Java 内置解析 XML API: DOM、SAX;
    • XML 解析框架 JDOM;
    • XML 解析框架 DOM4J;
    • XML 解析框架 XStream ;
    • 总结 。

    现在的软件项目都不是独立的一个项目,都是多系统协调工作。这样的话就涉及到系统间的通讯,通讯就会跟报文传输挂上关系。系统间使用怎样的报文格式进行通讯呢?有的使用固定长度格式报文;有的使用变长格式报文;有的使用 XML 格式报告。本分享主要和大家分享一下 XML 格式报文的解析。Java 是一个开源的语言,本分享将给大家介绍一下常用的 XML 解析框架及特点。

    • XML 的简介及一些常见概念
    • Java 内置解析 XML API: DOM、SAX
    • XML 解析框架 JDOM
    • XML 解析框架 DOM4J
    • XML 解析框架 XStream
    • 总结

    XML 的简介及一些常见概念

    XML 的概念

    XML 是 Extensible Markup Language 简称,中文翻译为可扩展标记语言。XML 是一种通用的数据交换格式,它的平台无关性、语言无关性、系统无关性,给数据集成与交互带来了极大的方便。XML 在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已。

    XML 可用来描述数据、存储数据、传输数据/交换数据。

    XML 文档节点的类型主要有:

    1. document:文档,代表整个文档(DOM 树的根节点);
    2. element:元素,表示一个元素;
    3. attribute:属性,代表一个属性;
    4. PCDATA(Parsed Character Data):文本;
    5. comment:注释,代表一个注释;
    6. DOCTYPE:主要验证文档内容的正确性;
    7. ENTITIES:实体;
    8. CDATA(Character Data):代表文档中的 CDATA 区段,文本不会被解析器解析。

    XML 的基本语法

    在使用过程中,请记住以下几个基本语法。

    • 声明格式,如下:
    <?xml version="1.0" encoding="UTF-8"?>  
    • 根节点:必须有一个根节点。
    • 标签:标签必须有结束且区分大小写,标签必须顺序嵌套。
    • 属性:必须使用引号引起值。
    • 空格会被保留。
    • 命名规则:命名必须见名知意。
      • 名字可包含字母、数字以及其他的字符。
      • 名字不能以数字或者标点符号开始。
      • 名字不能以字符“xml”(或者 XML、Xml)开始。
    • 名字不能包含空格。
    • 不应在 XML 元素名称中使用“:” ,这是由于它用于命名空间(NameSpaces)的保留字。
    • 标签优先于属性。
    • XML 命名空间可提供避免元素命名冲突的方法。
    • CDATA:字符数据,<![CDATA[字符数据]]> ,字符数据不进行转义。
    • 实体:使用方式为“&实体;”,XML 中有5个预定义的实体,如下表所示。
    实体名称含义备注
    <<小于
    >>大于
    &&和号
    ''单引号
    ""引号

    注释:在 XML 中,只有字符 "<" 和 "&" 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。

    XML 约束

    1.XML DTD 约束

    DTD 是 DocType Definition 的简称,中文翻译为文档类型定义,DTD 的作用是定义 XML 文档的合法构建模块。它使用一系列的合法元素来定义文档结构,用于约定 XML 的格式。规定了文档中所使用的元素、实体、元素的属性、元素与实体之间的关系。

    DTD主要作用有:

    • 使用 DTD 可以提供一种统一的格式。

    XML 的可扩展性为文档的作者提供了很高的灵活性,可有时候需要的是统一,要求某一类文档具有相同的结构。

    • 使用 DTD 可以保证数据交流和共享的顺利进行。
    • DTD 使用户能够不依赖具体的数据就知道文档的逻辑结构。

    在没有 XML 文档的时候,也可以根据 DTD 为 XML 文档编写样式单,编写处理程序,这样可以有效地提高工作效率。

    • 使用 DTD 可以验证数据的有效性。

    DTD 对文档的逻辑结构进行了约束,这种约束可以比较宽松,也可以十分严格。可以根据 DTD 检查数据,以验证其是否符合规定和要求,这可以保证数据的正确和有效。

    DTD 主要定义方式:

    (1)内部定义法,DTD 文件放在 XML 文件内部。

     <!DOCTYPE 根元素 [元素声明]>  

    请看下面的例子,book.xml:

        <?xml version="1.0" encoding="UTF-8" ?>    <!DOCTYPE bookstore [    <!ELEMENT bookstore (book+)>    <!ELEMENT book (bookname,author,price)>    <!ATTLIST book id CDATA #REQUIRED>    <!ELEMENT bookname (#PCDATA)>    <!ELEMENT author (#PCDATA)>    <!ELEMENT price (#PCDATA)>    ]>    <bookstore>    <book>            <bookname>带你飞培训教程</bookname>            <author>huangjinjin</author>            <price>1.00元</price>    </book>    <book>            <bookname>降龙十八讲秘籍</bookname>            <author>洪七公</author>            <price>0.01元</price>    </book>    </bookstore>

    (2)外部定义,请看下面这个例子。

    bookstore.dtd:

        <?xml version="1.0" encoding="UTF-8"?>      <!DOCTYPE bookstore [      <!ELEMENT bookstore (book+)>      <!ELEMENT book (bookname,author,price)>      <!ATTLIST book id CDATA #REQUIRED>      <!ELEMENT bookname (#PCDATA)>      <!ELEMENT author (#PCDATA)>      <!ELEMENT price (#PCDATA)>      ]>  

    book.xml:

        <?xml version="1.0" encoding="UTF-8" ?>    <!DOCTYPE bookstore SYSTEM "bookstore.dtd">    <bookstore>    <book>            <bookname>带你飞培训教程</bookname>            <author>huangjinjin</author>            <price>1.00元</price>    </book>    <book>            <bookname>降龙十八讲秘籍</bookname>            <author>洪七公</author>            <price>0.01元</price>    </book>    </bookstore>

    2.XML Schema 约束

    XML Schema 是基于 XML DTD 的替代者,XML Schema 描述 XML 文档的结构。XML Schema 语言也称作 XML Schema 定义(XML Schema Definition 简称 XSD)。DTD 不是通过 XML 语法定义文档结构,不能定义数据类型和限制;Schema 通过 XML 语法定义文档结构,可以定义数据类型和限制。

    XML Schema 对 XML 文件的主要约定有:

    • 定义可出现在 XML 文档中的元素;
    • 定义可出现在 XML 文档中的属性;
    • 定义哪个元素是子元素;
    • 定义子元素的次序;
    • 定义子元素的数目;
    • 定义元素是否为空,或者是否可包含文本;
    • 定义元素和属性的数据类型;
    • 定义元素和属性的默认值以及固定值。

    为何使用 Schema,原因有几下几点:

    • XML Schema 可针对未来的需求进行扩展;
    • XML Schema 更完善,功能更强大;
    • XML Schema 基于 XML 编写;
    • XML Schema 支持数据类型和限制;
    • XML Schema 支持命名空间。

    我们看下面这个例子。

    book.xsd 文件:

        <?xml version="1.0" encoding="UTF-8"?>    <schema xmlns="http://www.w3.org/2001/XMLSchema"     targetNamespace="http://www.mybook.org/BookSchema"    xmlns:tns="http://www.mybook.org/BookSchema" elementFormDefault="qualified">        <!-- 定义一个标签 -->        <element name="bookstore">            <!-- 复合类型 就是该标签含有子标签 -->            <complexType>                <!-- 含有不限定个数的子标签 -->                <sequence maxOccurs="unbounded">                    <!-- 定义一个子标签 -->                    <element name="book">                        <complexType>                            <sequence>                                <!-- 定义一个文本子标签 -->                                <element name="bookname" type="string" />                                <element name="author" type="string" />                                <element name="price" type="string" />                            </sequence>                            <attribute name="id" type="string"></attribute>                        </complexType>                    </element>                </sequence>            </complexType>        </element>    </schema>
      

    book.xml

        <?xml version="1.0" encoding="UTF-8" ?>    <bookstore        xmlns="http://www.w3.org/2001/XMLSchema-instance"        xmlns:nsbook="http://www.mybook.org/BookSchema"        nsbook:schemaLocation="http://www.mybook.org/BookSchema book.xsd">        <book id="1">            <bookname>带你飞培训教程</bookname>            <author>huangjinjin</author>            <price>1.00元</price>        </book>        <book id="2">            <bookname>降龙十八讲秘籍</bookname>            <author>洪七公</author>            <price>0.01元</price>        </book>    </bookstore>

    Java 内置解析 XML API: DOM、SAX

    DOM

    DOM的全称是 Document Object Model,即文档对象模型,W3C 组织推荐处理 XML 的一种方式。在应用程序中,基于 DOM 的 XML 分析器将一个 XML 文档转换成一个对象模型的集合(通常称 DOM 树),应用程序正是通过对这个对象模型的操作,来实现对 XML 文档数据的操作。通过 DOM 接口,应用程序可以在任何时候访问 XML 文档中的任何一部分数据,因此这种利用 DOM 接口的机制也被称作随机访问机制。

    DOM 接口提供了一种通过分层对象模型来访问 XML 文档信息的方式,这些分层对象模型依据 XML 的文档结构形成了一棵节点树。无论 XML 文档中所描述的是什么类型的信息,即便是制表数据、项目列表或一个文档,利用 DOM 所生成的模型都是节点树的形式。也就是说 DOM 强制使用树模型来访问 XML 文档中的信息。由于 XML 本质上就是一种分层结构,所以这种描述方法是相当有效的。

    DOM 树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个 XML 文档中的内容。然而,由于 DOM 分析器把整个 XML 文档转化成 DOM 树放在了内存中,因此当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且对于结构复杂的树的遍历也是一项耗时的操作。所以 DOM 分析器对机器性能的要求比较高,实现效率不十分理想。不过,由于 DOM 分析器所采用的树结构的思想与 XML 文档的结构相吻合,同时鉴于随机访问所带来的方便,因此 DOM 分析器还是有很广泛的使用价值的。

    其优点主要有:

    1. 形成了树结构,有助于更好的理解、掌握,且代码容易编写。
    2. 解析过程中,树结构保存在内存中,方便修改。

    其缺点主要有:

    1. 由于文件是一次性读取,所以对内存的耗费比较大。
    2. 如果 XML 文件比较大,容易影响解析性能且可能会造成内存溢出。

    DOM 操作 XML 例子,请见下面代码:

        // 创建一个DocumentBuilderFactory的对象    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();    // 创建一个DocumentBuilder的对象    try {        // 创建DocumentBuilder对象        DocumentBuilder db = dbf.newDocumentBuilder();        // 通过DocumentBuilder对象的parser方法加载books.xml文件到当前项目下        Document document = db.parse("C:\\Users\\Administrator\\Desktop\\xmlchat\\xml-chat\\src\\test\\resources\\3.xml");        // 获取所有book节点的集合        NodeList bookList = document.getElementsByTagName("book");        // 通过nodelist的getLength()方法可以获取bookList的长度        System.out.println("一共有" + bookList.getLength() + "本书");        // 遍历每一个book节点        for (int i = 0; i < bookList.getLength(); i++) {            System.out.println("=================下面开始遍历第" + (i + 1) + "本书的内容=================");            // 通过 item(i)方法 获取一个book节点,nodelist的索引值从0开始            Node book = bookList.item(i);            // 获取book节点的所有属性集合            NamedNodeMap attrs = book.getAttributes();            System.out.println("第 " + (i + 1) + "本书共有" + attrs.getLength() + "个属性");            // 遍历book的属性            for (int j = 0; j < attrs.getLength(); j++) {                // 通过item(index)方法获取book节点的某一个属性                Node attr = attrs.item(j);                // 获取属性名 值                System.out.print("属性名:" + attr.getNodeName()+", 属性值" + attr.getNodeValue());            }            // 解析book节点的子节点            NodeList childNodes = book.getChildNodes();            // 遍历childNodes获取每个节点的节点名和节点值            System.out.println("第" + (i + 1) + "本书共有" + childNodes.getLength() + "个子节点");            for (int k = 0; k < childNodes.getLength(); k++) {                // 区分出text类型的node以及element类型的node                if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {                    // 获取了element类型节点的节点名                    System.out.print("第" + (k + 1) + "个节点的节点名:" + childNodes.item(k).getNodeName());                    // 获取了element类型节点的节点值                    System.out.println("--节点值是:" + childNodes.item(k).getFirstChild().getNodeValue());                }            }            System.out.println("======================结束遍历第" + (i + 1) + "本书的内容=================");        }    } catch (Exception e) {        e.printStackTrace();    }

    SAX

    SAX 的全称是 Simple APIs for XML,即 XML 简单应用程序接口。与 DOM 不同,SAX 提供的访问模式是一种顺序模式,这是一种快速读写 XML 数据的方式。当使用 SAX 分析器对 XML 文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对 XML 文档的访问,因而 SAX 接口也被称作事件驱动接口。SAX 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。

    其优点主要有:

    1. 采用事件驱动模式,对内存耗费比较小。
    2. 适用于只处理 XML 文件中的数据时。

    其缺点主要有:

    1. 编码比较麻烦。
    2. 很难同时访问 XML 文件中的多处不同数据。

    SAX 处理 XML 例子,请见下面代码:

            // 获取Sax解析工程对象        SAXParserFactory factory = SAXParserFactory.newInstance();        try {            SAXParser parser = factory.newSAXParser();            // 新建xml处理器            SAXParserHandler handler = new SAXParserHandler();            parser.parse("C:\\Users\\Administrator\\Desktop\\xmlchat\\xml-chat\\src\\test\\resources\\3.xml", handler);            System.out.println("共有" + handler.getBookList().size() + "本书");            for (Book book : handler.getBookList()) {                System.out.println(book.getId());                System.out.println(book.getBookname());                System.out.println(book.getAuthor());                System.out.println(book.getPrice());            }        } catch (Exception e) {            e.printStackTrace();        }

    XML 处理器 SAXParserHandler 关键代码,如下:

            /**             * 解析xml元素             */        @Override        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {            // 调用DefaultHandler类的startElement方法            super.startElement(uri, localName, qName, attributes);            if (qName.equals("book")) {                bookIndex++;                // 创建一个book对象                book = new Book();                // 开始解析book元素的属性                System.out.println("============开始遍历某一本书的内容=================");                // 不知道book元素下属性的名称以及个数,如何获取属性名以及属性值                int num = attributes.getLength();                for (int i = 0; i < num; i++) {                    System.out.print("book元素的第" + (i + 1) + "个属性名是:" + attributes.getQName(i));                    System.out.println(", 属性值是:" + attributes.getValue(i));                    if (attributes.getQName(i).equals("id")) {                        book.setId(attributes.getValue(i));                    }                }            } else {                System.out.print("节点名是:" + qName +", ");            }        }        @Override        public void endElement(String uri, String localName, String qName) throws SAXException {            // 调用DefaultHandler类的endElement方法            super.endElement(uri, localName, qName);            // 判断是否针对一本书已经遍历结束            if (qName.equals("book")) {                bookList.add(book);                book = null;                System.out.println("===========结束遍历某一本书的内容=================");            } else if (qName.equals("bookname")) {                book.setBookname(value);            } else if (qName.equals("author")) {                book.setAuthor(value);            }  else if (qName.equals("price")) {                book.setPrice(value);            }         }        @Override        public void characters(char[] ch, int start, int length) throws SAXException {            super.characters(ch, start, length);            value = new String(ch, start, length);            if (!value.trim().equals("")) {                System.out.println("节点值是:" + value);            }        }

    XML 解析框架 JDOM

    JDOM 目的是成为 Java 特定文档模型,简化与 XML 的交互并且比使用 DOM 实现更快。由于是第一个 Java 特定模型,所以 JDOM 一直得到大力推广和促进。正在考虑通过“Java 规范请求 JSR-102”将它最终用作“Java 标准扩展”。从2000年初就已经开始了 JDOM 开发。JDOM 与 DOM 主要有两方面不同。第一,JDOM 仅使用具体类而不使用接口,这在某些方面简化了 API,但是也限制了灵活性;第二,API 大量使用了 Collections 类,简化了那些已经熟悉这些类的 Java 开发者的使用。

    JDOM 文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML 问题”。JDOM 对于大多数 Java/XML 应用程序来说非常有用,并且大多数开发者发现 API 比 DOM 容易理解得多。JDOM 还包括对程序行为的相当广泛检查以防止用户做任何在 XML 中无意义的事。然而它仍需要您充分理解 XML 以便做一些超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习 DOM 或 JDOM 接口都更有意义的工作。JDOM 自身不包含解析器。它通常使用 SAX2 解析器来解析和验证输入 XML 文档,尽管它还可以将以前构造的 DOM 表示作为输入。它包含一些转换器以将 JDOM 表示输出成 SAX2 事件流、DOM 模型或 XML 文本文档。JDOM 是在 Apache 许可证变体下发布的开放源码。同时需要注意的是 JDOM 目前分为两个版本,分别为JDOM 1.x 和 JDOM 2.x。

    其主要特征有:

    1. 仅使用具体类,而不使用接口。
    2. API 大量使用了 Collections 类。

    JDOM 解析 XML 的例子,如下:

        import java.io.File;    import java.io.FileInputStream;    import java.util.List;    import org.jdom2.Document;    import org.jdom2.Element;    import org.jdom2.input.SAXBuilder;    public class JDomTest {        public static void main(String[] args) {            try {                // 创建一个SAXBuilder对象                SAXBuilder sb = new SAXBuilder();                File file = new File("C:\\Users\\Administrator\\Desktop\\xmlchat\\xml-chat\\src\\test\\resources\\1.xml");                FileInputStream in = new FileInputStream(file);                // 构造文档对象                Document doc = sb.build(in);                // 获取根元素bookstore                Element root = doc.getRootElement();                // 取名字为book的所有元素                List<Element> books = root.getChildren("book");                for (int i = 0; i < books.size(); i++) {                    Element e = books.get(i);                    List<Element> sube = e.getChildren();                    System.out.println("第" + (i + 1) + "本书信息:");                    e = sube.get(0);                    System.out.println(e.getName() + "=" + e.getText());                    e = sube.get(1);                    System.out.println(e.getName() + "=" + e.getText());                    e = sube.get(2);                    System.out.println(e.getName() + "=" + e.getText());                }            } catch (Exception e) {                e.printStackTrace();            }        }    }

    XML 解析框架 DOM4J

    虽然 DOM4J 代表了完全独立的开发结果,但最初它是 JDOM 的一种智能分支。它合并了许多超出基本 XML 文档表示的功能,包括集成的 XPath 支持、 XML Schema 支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过 DOM4J API 和标准 DOM 接口具有并行访问功能。

    为支持所有这些功能,DOM4J 使用接口和抽象基本类方法。DOM4J 大量使用了 API 中的 Collections 类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然 DOM4J 付出了更复杂的 API 的代价,但是它提供了比 JDOM 大得多的灵活性。在添加灵活性、XPath 集成和对大文档处理的目标时,DOM4J 的目标与 JDOM 是一样的:针对 Java 开发者的易用性和直观操作。它还致力于成为比 JDOM 更完整的解决方案,实现在本质上处理所有 Java/XML 问题的目标。在完成该目标时,它比 JDOM 更少强调防止不正确的应用程序行为。

    DOM4J 是一个非常非常优秀的 Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是 Sun 的 JAXM 也在用 DOM4J。同时需要注意的是 DOM4J 目前也分为两个版本,分别为 DOM4J 1.x和 DOM4J 2.x。

    其特征主要有:

    1. JDOM 的一种智能分支,它合并了许多超出基本 XML 文档表示的功能。
    2. 它使用接口和抽象基本类方法。
    3. 具有性能优异、灵活性好、功能强大和极端易用的特点。
    4. 是一个开放源码的文件。

    DOM4J 解析 XML 的例子,如下:

        import java.io.File;    import java.util.Iterator;    import java.util.List;    import org.dom4j.Attribute;    import org.dom4j.Document;    import org.dom4j.Element;    import org.dom4j.io.SAXReader;    public class DOM4JTest {        public static void main(String[] args) {            try {                // 创建SAXReader的对象reader                SAXReader reader = new SAXReader();                // 通过reader对象的read方法加载books.xml文件,获取docuemnt对象。                Document document = reader.read(                        new File("C:\\Users\\Administrator\\Desktop\\xmlchat\\xml-chat\\src\\test\\resources\\1.xml"));                // 通过document对象获取根节点bookstore                Element element = document.getRootElement();                // 通过element对象的elementIterator方法获取迭代器                Iterator<Element> iter = element.elementIterator();                int index = 0;                // 遍历迭代器,获取根节点中的信息(书籍)                while (iter.hasNext()) {                    Element e = iter.next();                    System.out.println("第" + (index + 1) + "本书");                    List<Attribute> bookAttrs = e.attributes();                    for (Attribute attr : bookAttrs) {                        System.out.println("属性名:" + attr.getName() + ",属性值:" + attr.getValue());                    }                    index = index + 1;                    Iterator<Element> siter = e.elementIterator();                    while (siter.hasNext()) {                        e = siter.next();                        System.out.println(e.getName() + "=" + e.getStringValue());                    }                }            } catch (Exception e) {                e.printStackTrace();            }        }    }

    XML解析框架 XStream

    XStream 是一种 OXMapping 技术,是用来处理 XML 文件序列化的框架,将 JavaBean 序列化或将 XML 文件反序列化,不需要其它辅助类和映射文件,使得 XML 序列化不再繁索。另外,Xstream 也可以将 JavaBean 序列化成 Json 或反序列化,使用非常方便。Java 自带的 JAXB(Java Architecture for XML Binding) API 也有相应的功能。下面分别介绍下这两种 API 的使用方法。

    JAXB 介绍

    JAXB 相关的重要 Class 和 Interface 有:

    • JAXBContext 类,是应用的入口,用于管理 XML/Java 绑定信息。
    • Marshaller 接口,将 Java 对象序列化为 XML 数据。
    • Unmarshaller 接口,将 XML 数据反序列化为 Java 对象。

    JDK 中 JAXB 相关的重要 Annotation有:

    • @XmlType,将 Java 类或枚举类型映射到 XML 模式类型。
    • @XmlAccessorType(XmlAccessType.FIELD),控制字段或属性的序列化。FIELD 表示 JAXB 将自动绑定 Java 类中的每个非静态的(static)、非瞬态的(由 @XmlTransient 标注)字段到 XML。其他值还有 XmlAccessType.PROPERTY 和 XmlAccessType.NONE。
    • @XmlAccessorOrder,控制 JAXB 绑定类中属性和字段的排序。
    • @XmlJavaTypeAdapter,使用定制的适配器(即扩展抽象类 XmlAdapter 并覆盖 marshal()和 unmarshal()方法),以序列化 Java 类为 XML。
    • @XmlElementWrapper,对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的 XML 元素(称为包装器)。
    • @XmlRootElement,将 Java 类或枚举类型映射到 XML 元素。
    • @XmlElement,将 Java 类的一个属性映射到与属性同名的一个 XML 元素。
    • @XmlAttribute,将 Java 类的一个属性映射到与属性同名的一个 XML 属性。

    注意以下几点:

    • 对于要序列化(marshal)为 XML 的 Java 类,绝不能把成员变量声明为 public,否则运行将抛出异常 com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException
    • 对于 JAXB 相关的重要 Annotation 的声明,如 @Xml.....,可以放在成员变量的 setter() 或 getter() 方法上,两者中任选其一即可,但决不能放在成员变量上,否则运行将抛出异常 com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException

    我们看一个例子,Book2.java 对象:

        import javax.xml.bind.annotation.XmlAttribute;    import javax.xml.bind.annotation.XmlElement;    import javax.xml.bind.annotation.XmlRootElement;    @XmlRootElement    public class Book2 {        private String id;        private String bookname;        private String author;        private String price;        public String getId() {            return id;        }        @XmlAttribute        public void setId(String id) {            this.id = id;        }        public String getBookname() {            return bookname;        }        @XmlElement        public void setBookname(String bookname) {            this.bookname = bookname;        }        public String getAuthor() {            return author;        }        @XmlElement        public void setAuthor(String author) {            this.author = author;        }        public String getPrice() {            return price;        }        @XmlElement        public void setPrice(String price) {            this.price = price;        }    }

    将 JavaBean 转成 XML,如下:

        import java.io.FileOutputStream;    import java.io.StringWriter;    import javax.xml.bind.JAXBContext;    import javax.xml.bind.Marshaller;    //将java bean转成xml    public class JaxbMarshal {        public static void main(String[] args) {            try {                Book2 book = new Book2();                book.setId("1");                book.setAuthor("千年老二");                book.setBookname("葵花宝典");                book.setPrice("1234");                JAXBContext context = JAXBContext.newInstance(Book2.class);                Marshaller m = context.createMarshaller();                StringWriter sw = new StringWriter();                m.marshal(book, sw);                m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// 是否格式化                m.marshal(book, new FileOutputStream("src/main/java/book.xml"));                System.out.println(sw.toString());            } catch (Exception e) {                e.printStackTrace();            }        }    }

    将 XML 转成 JavaBean,如下:

        import java.io.File;    import javax.xml.bind.JAXBContext;    import javax.xml.bind.Unmarshaller;    //将xml转成java bean    public class JaxbUnMarshal {        public static void main(String[] args) {            try {                JAXBContext context = JAXBContext.newInstance(Book2.class);                Unmarshaller m = context.createUnmarshaller();                Book2 book = (Book2)m.unmarshal(new File("src/main/java/book.xml"));                System.out.println(book.getId());                System.out.println(book.getBookname());                System.out.println(book.getAuthor());                System.out.println(book.getPrice());            } catch (Exception e) {                e.printStackTrace();            }        }    }

    XStream 介绍

    XStream 是个很强大的工具,能将 Java 对象和 XML 之间相互转化。XStream 不在意 Java 类中成员变量是私有还是公有,也不在乎是否有默认构造函数。它调用方式也非常简单:从 XML 对象转化为 Java 对象,使用 fromXML() 方法;从 Java 对象序列化为 XML,toXML() 即可,很方便。XStream 也支持注解方式,这些都是为了简化输出而设计。

    XStream常用注解说明有:

    • @XStreamAlias 注解可在类与属性上,设置别名;
    • @XStreamAliasType 注解设置在类,设置类型别名;
    • @XStreamAsAttribute 注解设置在属性上,作用是将类内成员作为父节点属性输出;
    • @XStreamConverter 注解设置在属性上,注入转化器;
    • @XStreamConverters 注解设置在属性上,注入多个转化器;
    • @XStreamImplicit 常用在集合属性上,表明只把集合里的元素列序号到 XML中;
    • @XStreamInclude
    • @XStreamOmitField 注解可设置在属性上,表明该属性不会被序列化到 XML 中。

    接下来,我们看下 XStream 使用例子。

    Person 实体类,如下:

        import com.thoughtworks.xstream.annotations.XStreamAlias;    import com.thoughtworks.xstream.annotations.XStreamAliasType;    import com.thoughtworks.xstream.annotations.XStreamAsAttribute;    import com.thoughtworks.xstream.annotations.XStreamOmitField;    @XStreamAliasType("p")    public class Person    {        @XStreamAsAttribute        private int id;        @XStreamAlias("n")        private String name;        @XStreamAlias("a")        @XStreamOmitField        private int age;        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        public int getAge() {            return age;        }        public void setAge(int age) {            this.age = age;        }    }

    XStream 操作 XML,如下:

        import com.thoughtworks.xstream.XStream;    public class XStreamTest {        public static void main(String[] args)        {            Person person=new Person();            person.setName("独孤求败");            person.setAge(100);            XStream xstream = new XStream();            // 进行注解的检测  如果没有这行注解将不起作用            xstream.autodetectAnnotations(true);             //XML序列化            String xml = xstream.toXML(person);            System.out.println(xml);            //XML反序列化            Person person1=(Person)xstream.fromXML(xml);            System.out.println(person1.getName());            System.out.println(person1.getAge());        }    }

    备注: xstream.autodetectAnnotations(true) 的作用是开启注解扫描,如果没有改行代码,默认为 false,不开启注解扫描,这样的话 Person.java 将不起任何作用。

    总结

    我们综合看下 DMO、SAX 和 JDOM 三者之间的区别。

    (1)DOM:拉模型,把整个文档加载到内存中。

    • 优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
    • 缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
    • 使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。

    (2)SAX:推模型,事件驱动编程,基于回调 SAX ,事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。

    • 优点:不用事先调入整个文档,占用资源少;
    • 缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;
    • 使用场合:数据量较大的XML文档,占用内存高,机器内存少,无法一次加载XML到内存;只需XML文档的少量内容,很少回头访问;

    (3)JDOM:为减少 DOM、SAX 的编码量,出现了 JDOM。

    • 优点:20-80原则,极大减少了代码量,提供常用 API 减少重复劳动;
    • 使用场合:要实现的功能简单,如解析、创建等Java程序。

    再来看下三者之间的性能比较。

    (1)DOM4J 性能最好,连 Sun 的 JAXM 也在用 DOM4J。目前许多开源项目中大量采用 DOM4J,例如大名鼎鼎的 Hibernate 也用 DOM4J 来读取 XML 配置文件。如果不考虑可移植性,那就采用 DOM4J。

    (2)JDOM 和 DOM 在性能测试时表现不佳,在测试 10M 文档时内存溢出。在小文档情况下还值得考虑使用 DOM 和 JDOM。虽然 JDOM 的开发者已经说明 他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。另外,DOM 仍是一个非常好的选择。DOM 实现广泛应用于多种编程语言。它还是许多其它与 XML 相关的标准的基础,因为它正式获得 W3C 推荐(与基于非标准的 Java 模型相对),所以在某些类型的项目中可能也需要它(如在 JavaScript 中使用 DOM)。

    (3)SAX 表现较好,这要依赖于它特定的解析方式——事件驱动。一个 SAX 检测即将到来的 XML 流,但并没有载入到内存(当然当 XML 流被读入时,会有部分文档暂时隐藏在内存中)。

    这里提供下源码地址:https://gitee.com/hjj520/xml,大家可以自行下载学习。


    本文首发于GitChat,未经授权不得转载,转载需与GitChat联系。

    阅读全文: http://gitbook.cn/gitchat/activity/5aa3ab85291bf90af9b04b2c

    您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

    FtooAtPSkEJwnW-9xkCLqSTRpBKX

    展开全文
  • 常见XML两种解析方法

    万次阅读 2011-05-26 15:58:00
    基本的解析方式有两种,一种叫SAX,另一种叫DOM。SAX是基于事件流的解析,DOM是基于XML文档树结构的解析.假设我们XML的内容和结构如下: ddviplinuxm30下面是解析XMl常用的Dom和Sex方法:1.DOM生成和解析XML文档为 XML...
  • XML解析技术浅谈

    千次阅读 2010-10-16 10:23:00
    XML作为过去十年中出现的最流行的技术之一,得到了广泛的应用,而其中XML解析技术是...本文介绍了XML解析技术的研究动向,分析和比较了4种XML解析技术的优劣,并归纳总结了应用系统设计中选取合适的XML解析技术的原则。
  • Java XML解析技术

    千次阅读 2018-10-25 19:07:04
    **Java XML解析技术** **XML概述** 随着软件程序从独立的单机应用程序演化为分布式的企业系统,开发人员开始要面对一系列新的挑战。应用程序不再仅仅运行于一台机器上,而是会运行于多台机器上,并且这些机器的...
  • Spring OXM- 漫谈XML解析技术

    千次阅读 2017-11-22 04:53:03
    概述概述我们先从XML各种解析技术的发展历程谈起,并介绍一些主流 O/X Mapping组件的使用方法,比如XStream、Castor、JiBX、JAXB等。 从独立使用到与Spring整合逐步演变,揭开各O/X Mapping组件的神秘面纱,根据需要...
  • Android实现XML解析技术

    千次阅读 2012-07-06 17:35:12
    本文介绍在Android平台中实现对XML的三解析方式。 ... XML在各种开发中都广泛应用,Android也不例外。作为承载数据的一个重要角色,如何读写XML... 在Android中,常见XML解析器分别为DOM解析器、SAX解析器和P
  • 在这篇文章中,我对这四主流方案做一个不完全评测,仅仅针对遍历 XML 这块来测试,因为遍历 XML 是工作中使用最多的(至少我认为)。 下面会对这种进行测试【JSP、SAX、JDOM、DOM4J】  预 备<?xml version...
  • 这种方式不是官方标准,属于开源社区XML-DEV,几乎所有的XML解析器都支持它。 一、DOM解析:  一次性把xml文档加载成Document树,通过Document对象得到节点对象,通过节点对象访问xml文档内容
  • XML 解析技术之不完全测试

    千次阅读 2004-10-27 21:04:00
    在这篇文章中,我对这四主流方案做一个不完全评测,仅仅针对遍历 XML 这块来测试,因为遍历 XML 是工作中使用最多的(至少我认为)。预 备 测试环境: AMD 毒龙1.4G OC 1.5G、256M DDR333、Windows2000 Server ...
  • XML解析技术之VTD-XML 简介及代码实例

    千次阅读 2015-09-09 00:15:35
    第一部分:XML解析技术简介  XML(eXtensible Markup Language,可扩展标记语言)是由World Wide Web联盟(W3C)定义的元语言,即一关于语言的语言。 Xml的优势或者说力量源于它的数据独立性,广泛应用在...
  • Java中四种XML解析技术之不完全测试

    千次阅读 2007-09-04 21:40:00
    在这篇文章中,我对这四主流方案做一个不完全评测,仅仅针对遍历XML这块来测试,因为遍历XML是工作中使用最多的(至少我认为)。 预备 测试环境: AMD毒龙1.4G OC 1.5G、256M DDR333、Windows2000 Server SP4、...
  • XML文件常见解析技术介绍

    千次阅读 2011-03-19 18:17:00
    然而XML本身只是以纯文本对数据进行编码的一格式,要想利用XML,或者说利用XML文件中所编码的数据,必须先将数据从纯文本中解析出来,因此,必须有一个能够识别XML文档中信息的解析器,用来解释XML文档并...
  • XML-解析技术(dom解析,sax解析)

    千次阅读 2013-10-25 08:50:50
    XML解析方式分为两种:dom和sax  dom:(Document Object Model, 即文档对象模型) 是 W3C 组织推荐的处理 XML 的一种方式。  sax: (Simple API for XML) 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 ...
  • source: http://blog.csdn.net/u011179993/article/details/47415603 声明:本文转自http://www.blogjava.NET/orangelizq/archive/2009/07/19/287330.html,并对原文... ...=========================== ...摘要:XML
  • Xml文件有许多解析方式,在学习J2EE中就学过很多,比如DOM,DOM4j,SAX,JDOM等等。 在Android中,比较常见的有SAX,DOM和Pull这三解析方式。并且Android上对XML解析的支持是相当强大的,看一下 Andr
  • XML解析

    千次阅读 2016-10-08 23:38:39
    相关阅读 XML约束 Xml 格式数据的生成和解析 XML解析器 一、操作XML文档概述1、如何操作XML文档XML文档也是数据的一种,对数据的...2、XML解析技术XML解析方式分为两种:DOM(Document Object Model)和SAX(Simple A
  • xml解析技术及JDOM和DOM4J的比较

    千次阅读 2018-07-04 07:51:56
    ------------------------------------xml解析技术及JDOM和DOM4J的比较----------------------------------------1.操作XML文档概述 1 如何操作XML文档XML文档也是数据的一,对数据的操作也不外乎是“增删改查”...
  • 大话XML解析

    千次阅读 2016-06-01 13:41:43
    之前我写过一篇关于xml解析的文章:http://blog.csdn.net/sdksdk0/article/details/50749326,写的都是一些很基础的知识。今天这篇文章主要是进一步加深对xml的理解了使用,写的应该会更注重细节的内容。主要内容有...
  • XML解析之DOM解析详解

    万次阅读 多人点赞 2018-06-05 16:39:34
    Xml解析两种方式,一种是DOM解析,另一种是SAX解析,两种操作的方式如图。       二、DOM解析   基于DOM解析的xml分析器是将其转换为一个对象模型的集合,用树这种数据结构对信息进行储存。通过DOM...
  • XML解析分析

    千次阅读 2010-05-05 12:35:00
    本文介绍了XML解析技术的研究动向,分析和比较了4种XML解析技术的优劣,并归纳总结了应用系统设计中选取合适的XML解析技术的原则。1 引言XML(eXtensible Markup Language,可扩展标记语言)是由World Wide Web联盟...
  • SAX解析只能查询,不能实现增删方法,不常用,这里就不过得介绍了
  • XML解析&XML约束文件

    千次阅读 2018-01-29 15:40:36
    DTD约束和SCHEMA约束,以及XML解析,XML语法规则
  • 深入解读XML解析

    万次阅读 多人点赞 2016-02-26 20:42:35
    XML是指可扩展标记语言(eXtensible MarkupLanguage),它是一标记语言。它被设计的宗旨是描述数据(XML),而非显示数据(HTML)。   目前遵循的是W3C组织于2000年发布的XML1.0规范   应用场景: 1、描述数据 2、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 137,252
精华内容 54,900
关键字:

常见的两种xml解析技术