XML学习之Dom方式解析XML文件

来源:互联网 发布:阿里云 ecs 高级教程 编辑:程序博客网 时间:2024/05/14 08:03


             XML学习之Dom方式解析Xml文件

一、java解析XML概述

  1.Xml解析方式分为两种:Dom方式和SAX方式。

   (1)、DOM方式:Document Object Model,文档对象模型。这种方式是W3C推荐的处理XML的一种方式。

   (2)、SAXSimple API for XML。这种方式不是官方标准,属于开源社区XML-DEV,   但是几乎所有的XML解析器都支持它。

   (3)、优缺点比较

     Dom方式使用的是文档对象模型解析,它首先要将xml文件整个读入内存中,然后再来构建Dom对象,在DOM对象里,xml文件中的所有元素都可以当做节点(Node)对象来处理。这种方式优点是方便对文档进行增加、删除、修改、添加等操作,缺点是它首先要将整个文件读入内存中在解析,如果文件大。会很消耗内存,并且它的执行速度慢。

     SAX方式:采取读取一行文件就解析一行的方式对文件进行解析,这种方式执行速度快,占用内存少。缺点是,采用SAX解析只能对文件进行查询操作,不能进行其它操作,如果只进行读取XML文件。个人认为采用这种方式比较好。

二、JAVA中解析XML的开发工具包

 1JAXPJava API for XML Processing 开发包是JavaSE的一部分,它由以下几个包及其子包组成。

    org.w3c.dom:提供DOM方式解析XML的标准接口

    org.xml.sax:提供SAX方式解析XML的标准接口

    javax.xml:提供了解析XML文档的类

    javax.xml.parsers包中,定义了几个工厂类。可以通过调用这些工厂类,得到对XML  文档进行解析的DOMSAX解析器对象。

 2Dom4JDom4j是一个简单、灵活的开放源代码的库

 3JDom:是开源组织推出的解析开发包。好像还有很多其它开发工具包,不了解。就这三个吧。

三、使用Dom方式对XML文件进行解析。

   javax.xml.parsers 包中的DocumentBuilderFactory用于创建DOM模式的解析器对象 , DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法 ,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。

下面是一个使用Dom方式解析Xml文件的例子。

要解析的XML文件为

在项目src下有个book.xml文件。

 

<?xml version="1.0" encoding="UTF-8" standalone="no"?><书架>  <书 出版社="清华出版社">      <书名>JavaWeb开发</书名>      <作者>xxx</作者>      <优惠价>56</优惠价><价格>68.0</价格>  </书>   <书 出版社="出版社">      <书名>AJAX开发实战</书名>      <作者>xxx</作者>      <价格>100</价格>  </书></书架>


package cn.itheima.jaxp;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import org.junit.Test;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;/** * 使用DOM对象对XML文件的增删改查 * @author Administrator * */public class XMLCurdByDom {//获得DOM对象public static Document getXMLDocument(){DocumentBuilder builder=null;Document document=null;try {//调用 DocumentBuilderFactory.newInstance() 方法得到创建 DOM 解析器的工厂//调用工厂对象的 newDocumentBuilder方法得到 DOM 解析器对象builder=DocumentBuilderFactory.newInstance().newDocumentBuilder();//调用 DOM 解析器对象的 parse() 方法解析 XML 文档,得到代表整个文档的 Document 对象document=builder.parse("src/book.xml");} catch (Exception e) {e.printStackTrace();}return document;}/** * 保存文档。将修改后的文档保存到文件中去 * @param document */public static void saveXML(Document document){Transformer tf=null;try{tf=TransformerFactory.newInstance().newTransformer();tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));}catch (Exception e) {      throw new RuntimeException(e);}}/** * 遍历所有节点测试 */@Testpublic void testIterateNode(){//首页获得XML文档对象。Document document=this.getXMLDocument();this.iterateNode(document);}//查询书本信息@Testpublic  void queryBookInfo(){//先得到xml文档对象Document document=this.getXMLDocument();//得到所有节点为书名的一个集合//NodeList接口提供对节点的有序集合的抽象,没有定义或约束如何实现此集合。DOM 中的 NodeList 对象是活动的。 NodeList nl=document.getElementsByTagName("书名");    //输出要获得的节点对象的内容System.out.println(nl.item(0).getTextContent());}/** * 添加节点,本例中在书节点下添加一个特价节点。 */@Testpublic void addNode(){//获得文档对象Document document=this.getXMLDocument();//创建一个新的节点Node newNode=document.createElement("特价");//获得<书名>节点NodeList nl=document.getElementsByTagName("书");//设置文本节点newNode.setTextContent("100");//添加子节点nl.item(0).appendChild(newNode);newNode.setTextContent("50");nl.item(1).appendChild(newNode);//将修改后的文档保存到文件中去  this.saveXML(document);}/** * 遍历所有节点 * @param node */public static void iterateNode(Node node){if(node.getNodeType()==Node.ELEMENT_NODE){    System.out.println(node.getNodeName());}   for(int i=0;i<node.getChildNodes().getLength();i++)   {iterateNode(node.getChildNodes().item(i));}}/** * 修改第二本书的价格 */@Testpublic void updateXml(){//先得到文档对象Document document=this.getXMLDocument();//等到第二本书价格所对应的节点。Node node=document.getElementsByTagName("价格").item(1);node.setTextContent("100");this.saveXML(document);}//删除节点/** * 删除第二本书的特价信息 */@Testpublic void deleteNode(){//获得整个文档对象Document document=this.getXMLDocument();//获得要删除的节点对象Node node=document.getElementsByTagName("特价").item(0);//获得要删除节点对象的父节点,然后删除该节点node.getParentNode().removeChild(node);//保存文档对象this.saveXML(document);}//在指定的节点前插入节点@Testpublic void insertNode(){//获得整个文档对象Document document=this.getXMLDocument();//获得要在其前面插入节点的节点对象Node node=document.getElementsByTagName("价格").item(0);    //创建一个新的节点Node newChild=document.createElement("优惠价");newChild.setTextContent("56");//插入节点对象node.getParentNode().insertBefore(newChild, node);//保存文档对象this.saveXML(document);}//修改书的属性值@Testpublic void updateAttr(){//先获得文档的根节点对象Document document=this.getXMLDocument();    //获得要操作那个属性所对应的元素对象    Element element=(Element)document.getElementsByTagName("书").item(0);    element.setAttribute("出版社", "天宇出版社");    this.saveXML(document);}}