使用Apache Xerces解析XML文档
2009-01-15 14:02
537 查看
使用Apache Xerces解析XML文档
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://lavasoft.blog.51cto.com/62575/43951 |
使用Apache Xerces解析XML文档 一、技术概述 在用Java解析XML时候,一般都使用现成XML解析器来完成,自己编码解析是一件很棘手的问题,对程序员要求很高,一般也没有专业厂商或者开源组织实现的好。 Java解析XML的原理图如下: 目前Java XML解析器有十多种之多,解析原理有二:使用基于事件的XML简单API(Simple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object Module)称为DOM。Sun公司提供了Java API for XML Parsing(JAXP)接口来使用SAX和DOM,通过JAXP,我们可以使用任何与JAXP兼容的XML解析器。但并不是所有的Java XML解析工具都实现了SUN提供的接口。DOM4J就没有遵循SUN的JAXP规范,但非常优秀。 DOM 采用建立树形结构的方式访问 XML 文档,而 SAX 采用的事件模型。 DOM 是W3C组织推荐的处理XML的标准接口,DOM 解析器把 XML 文档转化为一个包含其内容的树,并可以对树进行遍历。用 DOM 解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用 DOM 解析器的时候需要处理整个 XML 文档,所以对性能和内存的要求比较高,尤其是遇到很大的 XML 文件的时候。由于它的遍历能力,DOM 解析器常用于 XML 文档需要频繁的改变的服务中。 SAX是由XML_DEV邮件列表的成员开发的,它不是某个官方机构的标准,也不由W3C组织或其他任何官方机构维护,但它是XML社区事实上的标准。虽然SAX只是“民间”标准,但是它在XML中的应用丝毫不比DOM少,几乎所有的XML解析器都支持它。SAX 解析器采用了基于事件的模型,它在解析 XML 文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX 这种扩展能力得到了更好的体现。但用 SAX 解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。 DOM和SAX只是定义了一些接口,以及某些接口的默认实现,一个应用程序要想利用DOM或SAX访问XML文档,还需要一个实现了DOM或SAX的解析器(实现DOM和SAX中定义的接口,提供DOM和SAX定义的功能)。 Apache的Xerces是一个使用非常广泛的解析其,它提供了DOM和SAX的调用接口,并有多种语言的实现版本,要利用Xerces访问XML文档,只需要在应用程序中构造一个解析器实现类的对象。 这里面还存在一个问题,虽然使用的是标准的DOM和SAX接口,由于不同的XML解析器的实现类是不同的,如果使用另外一种解析器,仍然需要修改应用程序,只不过修改的代码量较小,需要更改XML解析器实现类的类名,然后重新编译、发布。 然而,对于兼容JAXP的XML解析器,我们可以选用JAXP API,这样在更换兼容JAXP解析器的时候,就不用对已发布的程序做任何的改动。 JAXP开发包由javax.xml包、org.w3c.dom包、org.xml.sax包及其子包组成。在javax.xml.parsers包中,定义了几个工厂类,用于加载DOM和SAX的实现类。 使用JAXP API解析XML的原理如下: 二、使用DOM解析XML DOM的核心概念就是NODE(节点)。DOM在分析XML文档时,将组成XML文档的各个部分(元素,属性,文本,注释,处理指令等)映射成一个对象,这个对象就叫做节点。在内存中这些节点形成一棵树。整棵树就是一个节点,树中的每一个节点也是一棵树(子树)。DOM就是对这棵树的一个对象描述,我们通过访问树中的节点来存取XML文档的内容。 DOM定义了一个Node接口,用于表示文档树中一个节点。从这个接口派生出来更多的具体的接口。例如,表示整个文档的Document接口,表示XML文档中的一个元素的Element接口,表示元素属性的Attr接口,都是从Node接口派生而来的。在org.w3c.dom包中,表示XML文档各组成部分的接口的继承关系如图: 举个例子,引用java web开发大全,有改动: students.xml ---------------------------------------------------------------------- <?xml version="1.0" encoding="GB2312"?> <?xml-stylesheet type="text/xsl" href="students.xsl"?> <students> <student sn="01"> <name>张三</name> <age>18</age> </student> <student sn="02"> <name>李四</name> <age>20</age> </student> </students> ---------------------------------------------------------------------- public class DOMStudentsInfo { public static void main(String[] args) { //获取生成 DOM 对象树的解析器 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { //从 DocumentBuilderFactory获取 DocumentBuilder实例 DocumentBuilder db = dbf.newDocumentBuilder(); File file = new File("students.xml"); ////从 XML 文档获取 DOM 文档实例 Document doc = db.parse(file); //获取某节点的集合 NodeList nl = doc.getElementsByTagName("student"); int len = nl.getLength(); for (int i = 0; i < len; i++) { Element eltStu = (Element) nl.item(i); Node eltName = eltStu.getElementsByTagName("name").item(0); Node eltAge = eltStu.getElementsByTagName("age").item(0); String name = eltName.getFirstChild().getNodeValue(); String age = eltAge.getFirstChild().getNodeValue(); System.out.print("姓名:"); System.out.println(name); System.out.print("年龄:"); System.out.println(age); System.out.println("----------------------------/n"); } } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 运行结果: 姓名:张三 年龄:18 ---------------------------- 姓名:李四 年龄:20 ---------------------------- Process finished with exit code 0 关于Node接口的更多信息,可以参看JDK的API文档。 三、使用SAX解析XML data_10k.xml ---------------------------------------------------------------------- <?xml version="1.0" encoding="GB2312"?> <?xml-stylesheet type="text/xsl" href="students.xsl"?> <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> ---------------------------------------------------------------------- public class MyXMLReader2 extends DefaultHandler { java.util.Stack tags = new java.util.Stack(); public MyXMLReader2() { super(); } public static void main(String args[]) { long lasting = System.currentTimeMillis(); try { SAXParserFactory sf = SAXParserFactory.newInstance(); SAXParser sp = sf.newSAXParser(); MyXMLReader2 reader = new MyXMLReader2(); 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); } } 运行结果: 车牌号码:a1234车牌号码: 地址:四川省xx县xx镇xx路x段xx号 地址: 地址: 车牌号码:b1234车牌号码: 地址:四川省xx市xx乡xx村xx组 地址: 地址: 运行时间:327 毫秒 Process finished with exit code 0 四、使用DOM4j解析xml public class MyXMLReader4 { 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) + " 毫秒"); } } 五、使用JDOM解析xml public class MyXMLReader3 { 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) + " 毫秒"); } } 六、使用JAXP解析XML public class MyXMLReader1 { 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) + " 毫秒"); } } |
相关文章推荐
- 使用Apache Xerces解析XML文档
- 使用Apache Xerces解析XML文档
- 使用Apache Xerces解析XML文档
- 使用Apache Xerces解析XML文档
- (转)使用Apache Xerces解析XML文档
- XML第十三讲:使用DOM解析XML文档
- 使用SimpleXML函数来加载和解析XML文档
- IOS学习笔记27—使用GDataXML解析XML文档
- iOS 获取xml文档并解析(使用GDataXML)
- 使用Digester解析XML文档示例
- XML案例(使用DOM4J解析XML文档)
- 使用 Perl 的 XML::Simple 解析 XML 文档
- 使用commons-digester解析XML文档示例
- android应用中使用xmlpull解析xml文档失败
- 使用GDataXML解析XML文档
- windows下使用xerces -c解析XML
- 使用dom4j解析XML文档
- 如何利用Xerces C++解析包含中文字符的XML文档
- 使用DOM 解析XML文档
- 简单介绍使用Python解析并修改XML文档的方法