Java解析XML文档——dom解析xml

Java解析XML文档——dom解析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解析器。
  
    JAXP接口包含了三个包:
  
    (1)org.w3c.dom
  
    W3C推荐的用于XML标准规划文档对象模型的接口。
  
    (2)org.xml.sax
  
    用于对XML进行语法分析的事件驱动的XML简单API(SAX)
  
    (3)javax.xml.parsers解析器工厂工具,程序员获得并配置特殊的特殊语法分析器。
  
    二、前提
  
    DOM编程不要其它的依赖包,因为JDK里自带的JDK里含有的上面提到的org.w3c.dom、org.xml.sax 和javax.xml.parsers包就可以满意条件了。
  
    三、使用DOM解析XML文档
  
    我们现在来看看DOM是如何解析XML的吧!同样的,我将从一个简单的不能再简单的例子来说明DOM是如何解析XML文档的,先让我们看看XML是什么内容吧:
  
    《?xml version="1.0" encoding="gb2312"?>
  
    《books>
  
    《book email="zhoujunhui">
  
    《name>rjzjh《/name>
  
    《price>jjjjjj《/price>
  
    《/book>
  
    《/books>
  
    简单的不能再简单了。但是该有的都有了,根元素、属性、子节点。好了,能反应问题就行了,下面来看看解析这个XML文件的Java代码吧!
  
    1 public class DomParse {
  
    2
  
    public DomParse(){
  
    3
  
    DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
  
    4
  
    try {
  
    5
  
    DocumentBuilder dombuilder=domfac.newDocumentBuilder();
  
    6
  
    InputStream is=new FileInputStream("bin/library.xml");
  
    7
  
    Document doc=dombuilder.parse(is);
  
    8
  
    9
  
    Element root=doc.getDocumentElement();
  
    10
  
    NodeList books=root.getChildNodes();
  
    11
  
    if(books!=null){
  
    12
  
    for(int i=0;i<books.getlength();i++){
  
    13
  
    Node book=books.item(i);
  
    14
  
    if(book.getNodeType()==Node.ELEMENT_NODE){
  
    15
  
    String email=book.getAttributes().getNamedItem("email").getNodeValue();
  
    16
  
    System.out.println(email);
  
    17
  
    for(Node node=book.getFirstChild();node!=null;node=node.getNextSibling()){
  
    18
  
    if(node.getNodeType()==Node.ELEMENT_NODE){
  
    19
  
    if(node.getNodeName().equals("name")){
  
    20
  
    String name=node.getNodeValue();
  
    21
  
    String name1=node.getFirstChild().getNodeValue();
  
    22
  
    System.out.println(name);
  
    23
  
    System.out.println(name1);
  
    24
  
    }
  
    25
  
    if(node.getNodeName().equals("price")){
  
    26
  
    String price=node.getFirstChild().getNodeValue();
  
    27
  
    System.out.println(price);
  
    28
  
    }
  
    29
  
    }
  
    30
  
    }
  
    31
  
    }
  
    32
  
    }
  
    33
  
    }
  
    34
  
    } catch (ParserConfigurationException e) {
  
    35
  
    e.printStackTrace();
  
    36
  
    } catch (FileNotFoundException e) {
  
    37
  
    e.printStackTrace();
  
    38
  
    } catch (SAXException e) {
  
    39
  
    e.printStackTrace();
  
    40
  
    } catch (IOException e) {
  
    41
  
    e.printStackTrace();
  
    42
  
    }
  
    43
  
    }
  
    44
  
    public static void main(String[] args) {
  
    45
  
    new DomParse();
  
    46
  
    }
  
    47 }
  
    四、代码解释
  
    先看看这个程序引用类:
  
    import java.io.FileInputStream;
  
    import java.io.FileNotFoundException;
  
    import java.io.IOException;
  
    import java.io.InputStream;
  
    import javax.xml.parsers.DocumentBuilder;
  
    import javax.xml.parsers.DocumentBuilderFactory;
  
    import javax.xml.parsers.ParserConfigurationException;
  
    //下面主要是org.xml.sax包的类
  
    import org.w3c.dom.Document;
  
    import org.w3c.dom.Element;
  
    import org.w3c.dom.Node;
  
    import org.w3c.dom.NodeList;
  
    import org.xml.sax.SAXException;
  
    上面那么简单的代码一看就明白了,但是为了介绍个DOM编程的大概还是来看看这个程序吧:
  
    (1)得到DOM解析器的工厂实例
  
    DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
  
    得到javax.xml.parsers.DocumentBuilderFactory;类的实例就是我们要的解析器工厂
  
    (2)从DOM工厂获得DOM解析器
  
    DocumentBuilder dombuilder=domfac.newDocumentBuilder();
  
    通过javax.xml.parsers.DocumentBuilderFactory实例的静态方法newDocumentBuilder()得到DOM解析器
  
    (3)把要解析的XML文档转化为输入流,以便DOM解析器解析它
  
    InputStream is=new FileInputStream("bin/library.xml");
  
    InputStream是一个接口。
  
    (4)解析XML文档的输入流,得到一个Document
  
    Document doc=dombuilder.parse(is);
  
    由XML文档的输入流得到一个org.w3c.dom.Document对象,以后的处理都是对Document对象进行的
  
    (5)得到XML文档的根节点
  
    Element root=doc.getDocumentElement();
  
    在DOM中只有根节点是一个org.w3c.dom.Element对象。
  
    (6)得到节点的子节点
  
    NodeList
  
    books=root.getChildNodes();
  
    for(int i=0;i<books.getlength();i++){
  
    Node book=books.item(i);
  
    }
  
    这是用一个org.w3c.dom.NodeList接口来存放它所有子节点的,还有一种轮循子节点的方法,后面有介绍
  
    (7)取得节点的属性值
  
    String email=book.getAttributes().getNamedItem("email").getNodeValue();
  
    System.out.println(email);
  
    注意,节点的属性也是它的子节点。它的节点类型也是Node.ELEMENT_NODE
  
    (8)轮循子节点
  
    for(Node node=book.getFirstChild();node!=null;node=node.getNextSibling()){
  
    if(node.getNodeType()==Node.ELEMENT_NODE){
  
    if(node.getNodeName().equals("name")){
  
    String name=node.getNodeValue();
  
    String name1=node.getFirstChild().getNodeValue();
  
    System.out.println(name);
  
    System.out.println(name1);
  
    }
  
    if(node.getNodeName().equals("price")){
  
    String price=node.getFirstChild().getNodeValue();
  
    System.out.println(price);
  
    }
  
    }
  
    这段代码的打印输出为:
  
    null
  
    alterrjzjh
  
    jjjjjj
  
    从上面可以看出
  
    String name=node.getNodeValue();
  
    是一个空值。而
  
    String name1=node.getFirstChild().getNodeValue();
  
    才是真正的值,这是因为DOM把《name>rjzjh《/name>也当作是两层结构的节点,其父节点 
  
   
   

 

#日志日期:2008-5-25 星期日(Sunday) 晴

 

评论人:pizazzlk 评论日期:2008-5-25 15:55
  XML 文件如下:
  
  <?xml version='1.0' encoding='utf-8'?>
  <links>
  <link>
   <text>JSP Insider</text>
   <url>http://www.jspinsider.com</url>
   <date>
   <day>2</day>
   <month>1</month>
   <year>2001</year>
   </date>
  </link>
  
   <link>
   <text>ASP Insider</text>
   <url>http://www.Aspinsider.com</url>
   <date>
   <day>2</day>
   <month>1</month>
   <year>2001</year>
   </date>
   </link>
  </links>
  
  与XML对应的JAVA对象:
  
  package tiany.lijun.readxml;
  public class obj
   {
   String text=null;
   String url=null;
   Datee d=null;
   public obj()
   {
   d=new Datee();
   }
  public String getText()
  {
   return text;
  }
  public void setText(String text)
  {
   this.text = text;
  }
  public String getUrl()
  {
   return url;
  }
  public void setUrl(String url)
  {
   this.url = url;
  }
  public Datee getD()
  {
   return d;
  }
  public void setD(Datee d)
  {
   this.d = d;
  }
  
  
  public class Datee //内置对象 对应日期
  {
   String day=null;
   String month=null;
   String year=null;
   public String getDay()
   {
   return day;
   }
   public void setDay(String day)
   {
   this.day = day;
   }
   public String getMonth()
   {
   return month;
   }
   public void setMonth(String month)
   {
   this.month = month;
   }
   public String getYear()
   {
   return year;
   }
   public void setYear(String year)
   {
   this.year = year;
   }
   
  }
  
  
   }
  
  读取XML的主文件:
  
  package tiany.lijun.readxml;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.HashSet;
  import java.util.Iterator;
  import javax.xml.parsers.SAXParser;
  import javax.xml.parsers.SAXParserFactory;
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.DefaultHandler;
  
  public class readxml extends DefaultHandler
  {
   public obj vo;
   private String str;
   private HashSet set;
  
   public void endDocument() throws SAXException
   {
   }
  
   public void startDocument() throws SAXException
   {
  set = new HashSet();
   }
  
   public void startElement(String p0, String p1, String p2, Attributes p3) throws SAXException
   {
  if (p2.equals("link"))
  {
   vo = new obj();
  }
   }
  
   public void endElement(String p0, String p1, String p2) throws SAXException
   {
  if (p2.equals("text"))
  {
   vo.setText(str);
  }
  else if (p2.equals("url"))
  {
   vo.setUrl(str);
  }
  else if (p2.equals("link"))
  {
   set.add(vo);
   vo = null;
  }
  else if (p2.equals("links"))
  {
   display();
  }
  else if (p2.equals("day"))
  {
   vo.getD().setDay(str);
  }
  else if (p2.equals("month"))
  {
   vo.getD().setMonth(str);
  }
  else if (p2.equals("year"))
  {
   vo.getD().setYear(str);
  }
   }
  
   public void characters(char[] p0, int p1, int p2) throws SAXException
   {
  str = new String(p0, p1, p2);
   }
  
   public void display()
   {
  Iterator it = set.iterator();
  while (it.hasNext())
  {
   obj v = (obj) it.next();
   System.out.println(v.getText());
   System.out.println(v.getUrl());
   System.out.println(v.getD().getDay());
   System.out.println(v.getD().getMonth());
   System.out.println(v.getD().getYear());
   System.out.println("-------------------------------");
  }
   }
  
   static public void main(String[] args)
   {
  String filename = null;
  boolean validation = false;
  filename = "tomcat-usersw.xml";
  SAXParserFactory spf = SAXParserFactory.newInstance();
  SAXParser saxParser = null;
  
  try
  {
   saxParser = spf.newSAXParser();
  }
  catch (Exception ex)
  {
   System.err.println(ex);
   System.exit(1);
  }
  try
  {
   saxParser.parse(new File(filename), new readxml());
  }
  catch (SAXException se)
  {
   System.err.println(se.getMessage());
   System.exit(1);
  }
  catch (IOException ioe)
  {
   System.err.println(ioe);
   System.exit(1);
  }
   }
  
  }
  

评论人:pizazzlk 评论日期:2008-5-25 15:56
  回复中为SAX解析XML方式

评论人:pizazzlk 评论日期:2008-5-25 15:58
  JDOM解析XML文件
  
  
  2、jdom
  
  package org.lyj.xml;
  
  import org.jdom.output.Format;
  import org.jdom.Document;
  import java.io.IOException;
  import org.jdom.input.SAXBuilder;
  import org.jdom.output.XMLOutputter;
  import org.jdom.JDOMException;
  
  /**
   * <p>Title: </p>
   *
   * <p>Description: </p>
   *
   * <p>Copyright: Copyright (c) 2005</p>
   *
   * <p>Company: </p>
   *
   * @author not attributable
   * @version 1.0
   */
  public class JdomWriter {
   public JdomWriter() {
   }
  
   public void write(){
   try {
   SAXBuilder builder = new SAXBuilder();
   Document doc = builder.build("aa.xml");
   XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setEncoding("utf-8"));
   outputter.output(doc, new java.io.FileOutputStream("bb.xml"));
   } catch (JDOMException e) {
   e.printStackTrace();
   } catch (IOException e) {
   e.printStackTrace();
   }
  
  
   }
   public static void main(String args[]){
   JdomWriter jd = new JdomWriter();
   jd.write();
   }
  }
  
  
  
    

评论人:pizazzlk 评论日期:2008-5-25 16:00
  Java解析XML文件2007-08-17 11:17package com.yc.ycportal.ge.util;
  
  import java.io.FileInputStream;
  import java.util.Enumeration;
  import java.util.List;
  import java.util.Properties;
  import java.util.ResourceBundle;
  
  import javax.xml.parsers.SAXParser;
  import javax.xml.parsers.SAXParserFactory;
  
  import org.jdom.Document;
  import org.jdom.Element;
  import org.jdom.input.SAXBuilder;
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.DefaultHandler;
  
  /**
  * @author 
  * 本类的作用是对properties和xml文件的解析,重点在于包括xml文件的两种解析方式
  * 现在有三种用于Java的流行xml解析技术,文档对象模型(Document Object Model,DOM),基于W3C的
  * 成熟标准,2、用于XML的简单API(Simple API for XML),第一个被广泛采用的用Java编写的XML API
  * 是一个事实上的标准,3、用于XML的数据流API(Straming API for XML,StAX),JSR-173中采用
  * 的一个新解析模型
  */
  public class ParseFile {
  
  public static ParseFile getInterface(){
   return new ParseFile();
  }
  
  /**解析Properties文件获取数据信息*/
  /**
   *properties的文件格式为
   *username=sa
   *userpass=123以第一等号为标准,后面为它的值 
   */
  public List getPropertes(String fileName){
   List list = null;
   ResourceBundle rb = ResourceBundle.getBundle(fileName);
   list.add(rb.getString("username"));
   list.add(rb.getString("userpass"));
   return list;
  }
  /**用SAX方式解析XML文件获取数据信息,创建一个解析XML文件的内部类解析器*/
  class ParseXML extends DefaultHandler{
   //所有的方法是子类重写父类的方法
   String currentName = null;
   StringBuffer currentValue = new StringBuffer();
   Properties properties = null;
   
   //接收元素开始的通知。 
   //默认情况下,不执行任何操作。应用程序编写者可以在子类中重写此方法,以便在每个元素的开始处采取特定的操作
   public void startElement(String uri,String localName,String qName,Attributes attributes)throws SAXException{
   this.currentValue.delete(0, this.currentValue.length());
   this.currentName = qName;
   }
   //接收元素中字符数据的通知
   //默认情况下,不执行任何操作。应用程序编写者可以重写此方法,以便对每块字符数据采取特定的措施
   //如将该数据添加到节点或缓冲区,或者将该数据打印到文件。
   public void characters(char[] ch,int start,int length)throws SAXException{
   this.currentValue.append(ch,start,length);
   }
   //接收元素结束的通知
   //默认情况下,不执行任何操作。应用程序编写者可以在子类中重写此方法,以便在每个元素的结束处采取特定的操作
   //如,结束树节点或将输出写入文件。
   public void endElement(String uri,String localName,String qName)throws SAXException{
   this.properties.put(qName.toLowerCase(), this.currentValue.toString().trim());
   }
   //返回存储XML信息数据的properties
   public Properties getProperties(){
   return this.properties;
   }
  }
  public List getSAXXml(String fileName)throws Exception{
   List list = null;
   ParseXML parsexml = new ParseXML();
   Properties properties = null;
   SAXParserFactory factory = SAXParserFactory.newInstance();
   //如果由此代码生成的解析器将提供对 XML 名称空间的支持,则为 true;否则为 false。
   factory.setNamespaceAware(false);
   //指定由此代码生成的解析器将验证被解析的文档。默认情况下,其值设置为 false
   factory.setValidating(false);
   SAXParser parser = factory.newSAXParser();
   //使用指定的DefaultHandler将指定文件的内容解析为 XML。
   parser.parse(fileName, parsexml);
   properties = parsexml.getProperties();
   Enumeration em = properties.keys();
   while(em.hasMoreElements()){
   list.add(properties.get(em.nextElement().toString()));
   }
   return list;
  }
  /**用Dom方式解析XML文件获取数据信息,比较容易理解和掌握的一种方式very good*/
  public List getDOMXml(String fileName)throws Exception{
   List list = null;
   SAXBuilder builder = new SAXBuilder();
   Document document = builder.build(new FileInputStream(fileName));
   //document.getRootElement()获取根节点返回一个Element
   List listchild = document.getRootElement().getChildren("table");
   for(int i=0;i<listchild.size();i++){
   Element e = (Element)listchild.get(i);
   String tableName = e.getChild("tablename").getText();
   List nextchild = e.getChild("fields").getChildren("field");
   list.add(tableName);
   for(int j=0;j<nextchild.size();j++){
   Element child = (Element)nextchild.get(j);
   list.add(child.getAttributeValue("name"));
   }
   }
   //返回的List的结构是以表名为0个索引位置后面依次为表的字段名称,附带XML文件描述
   return list;
  }
  }
  
  
  <?xml version="1.0" encoding="gb2312" ?>
  <tables>
  <table> 
   <tablename>dic_rate_zhwd</tablename>
   <fields>
   <field name="organ_id" type="string"/>
   <field name="business_id" type="string"/>
   <field name="business_name" type="string"/>
   <field name="rate" type="double"/>
   </fields>
  </table>
  </tables>
   
  
posted @ 2013-07-23 21:00  meimao5211  阅读(325)  评论(0编辑  收藏  举报