posts - 22, comments - 32, trackbacks - 0, articles - 71
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Java DOM 解析 XML详解

Posted on 2010-03-02 15:04 为自己代言 阅读(20866) 评论(2)  编辑  收藏
 

DOM解析器的接口已经被W3C标准化了。org.w3.dom包包含了接口类型的定义,比如:

DocumentElement等。不同的提供者,比如Apache OrganizationIBM都编写了实现这些接口的DOM解析器。SUN公司的XML处理JAVA APIJava API for XML Processing,JAXP

库实际上可以插入到这些解析器中的任意一个中。但是SUN公司也在JAVA SDK中包含了自己的DOM解析器。在本文中我使用的就是JAVA的解析器。

1:要读入一个XML文档,首先要一个DocumentBuilder对象,可以这样得到:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();

2:现在可以从文件中去读取一个XML文件了(文件路径:"F:""employees.xml"

    得到XML文件有三种方式:

1:通过文件方式读取:

File file=new File("F:""employees.xml");

Document doc=builder.parse(file);

2:通过一个URL方式读取:

 URL u=new URL("http://java.sun.com/index.html")

Document doc=builder.parse(u);

3:可以能过java IO 流的读取:

       FileInputStream inputstream = new FileInputStream(

                  "F:""employees.xml");

    Document doc=builder.parse(inputstream);

这里就写这么多了,在详细的请自己去查查阅资料。

下边是employees.xml 这个XML文件的内容:

    <?xml version="1.0" encoding="GBK"?>

<employees>

<employee email="zzzlyr@163.com">

<name>李明</name>

<sex>女孩子</sex>

<age>30</age>

</employee>

<employee email="zzzlyr112@163.com">

<name>张钊钊</name>

<sex></sex>

<age>28</age>

</employee>

</employees>

publicvoid parseXml(String fileName) {

       try {

           DocumentBuilderFactory factory = DocumentBuilderFactory

                  .newInstance();

           DocumentBuilder builder = factory.newDocumentBuilder();

           Document document = builder.parse(fileName);

           // 1.获得文档根元素对对象;

           Element root = document.getDocumentElement();

           // 获得文档根元素下一级子元素所有元素;

           NodeList nodeList = root.getChildNodes();

           System.out.println(root.getNodeName());

           if (null != root) {

              for (int i = 0; i < nodeList.getLength(); i++) {

                  Node child = nodeList.item(i);

                  // 输出child的属性;

                  System.out.println(child);

                 

//                if (child.getNodeType() == Node.ELEMENT_NODE) {

//                   System.out.println(child.getAttributes().getNamedItem(

//                          "email").getNodeValue());

//                }

//

//                for (Node node = child.getFirstChild(); node != null; node = node

//                       .getNextSibling()) {

//

//                   if (node.getNodeType() == Node.ELEMENT_NODE) {

//                       if ("name".equals(node.getNodeName())) {

//                          System.out.println(node.getFirstChild()

//                                 .getNodeValue());

//                       }

//                   }

//                   if (node.getNodeType() == Node.ELEMENT_NODE) {

//                       if ("sex".equals(node.getNodeName())) {

//                           System.out.println(node.getFirstChild()

//                                 .getNodeValue());

//                       }

//                   }

//                   if (node.getNodeType() == Node.ELEMENT_NODE) {

//                       if ("age".equals(node.getNodeName())) {

//                          System.out.println(node.getFirstChild()

//                                 .getNodeValue());

//                       }

//                   }

//                }

              }

           }

       } catch (ParserConfigurationException e) {

           e.printStackTrace();

       } catch (IOException e) {

           e.printStackTrace();

       } catch (SAXException e) {

           e.printStackTrace();

       }

    }

我为了研究解析过程把写好的代码注释掉了,看这层输出结果:

employees

[#text:

]

[employee: null]

[#text:

]

[employee: null]

[#text:

]

第一个是整个文档的根元素名称,下边结果是第一层for输出结果,从结果可见而知

遍历了整个XML文件的所有子元素进行输出,如果不清楚可以和原XML文件对比可知

去掉注释部分结果如下:

employees

zzzlyr@163.com

李明

女孩子

30

zzzlyr112@163.com

张钊钊

28

从结果可知,DOM解析过程是先解析整个XML文件所有子元素,然后在能过第二个for

解析子元素下的子元素;

但是为什么第一个有类似于这样东西[#text:] 这是查了半天资料,原因是XML 文件元素之间的空白字符也是一个元素,<employees></employees>这之间空白;

child.getNodeType() == Node.ELEMENT_NODE代码可以忽略掉类似于这样东西;

这是解析,还有创建XML文档,自己看代码吧,我不多解释了;

整个代码:

package com.junhai.xml.test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Attr;
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;

import com.sun.org.apache.xerces.internal.util.XMLDocumentFilterImpl;

public class DomXmlDemo extends XMLDocumentFilterImpl implements XmlDocument {
 private Document document;

 public void init() {
  try {
   DocumentBuilderFactory factory = DocumentBuilderFactory
     .newInstance();
   DocumentBuilder builder = factory.newDocumentBuilder();
   this.document = builder.newDocument();

  } catch (ParserConfigurationException e) {
   System.out.println(e.getMessage());
  }
 }

 public void createXml(String fileName) {
  this.init();
  // 创建XML文件根节点;
  Element root = this.document.createElement("employees");
  this.document.appendChild(root);
  // 创建XML文件根节点子节点;
  Element employee = this.document.createElement("employee");
  // 向根节点添加属性节点;
  Attr email = this.document.createAttribute("email");
  email.setNodeValue("zzzlyr@163.com");
  // 把属性节点对象,追加到达根节点上去;
  employee.setAttributeNode(email);

  Element name = this.document.createElement("name");
  // 向XML文件根节点子节点追加数据;
  name.appendChild(this.document.createTextNode("李明"));

  // 在把子节点的属性追加到子节点中元素中去;
  employee.appendChild(name);

  Element sex = this.document.createElement("sex");
  sex.appendChild(this.document.createTextNode("女孩子"));
  employee.appendChild(sex);

  Element age = this.document.createElement("age");
  age.appendChild(this.document.createTextNode("30"));
  employee.appendChild(age);
  root.appendChild(employee);

  
 
  // 创建XML文件根节点子节点;
  Element employee2 = this.document.createElement("employee");
  // 向根节点添加属性节点;
  Attr email2 = this.document.createAttribute("email");
  email2.setNodeValue("zzzlyr2@163.com");
  // 把属性节点对象,追加到达根节点上去;
  employee2.setAttributeNode(email2);
  Element name2 = this.document.createElement("name");
  // 向XML文件根节点子节点追加数据;
  name2.appendChild(this.document.createTextNode("张钊钊"));

  // 在把子节点的属性追加到子节点中元素中去;
  employee2.appendChild(name2);

  Element sex2 = this.document.createElement("sex");
  sex2.appendChild(this.document.createTextNode("男"));
  employee2.appendChild(sex2);

  Element age2 = this.document.createElement("age");
  age2.appendChild(this.document.createTextNode("28"));
  employee2.appendChild(age2);
  root.appendChild(employee2);
  
  
  
  
  
  TransformerFactory tf = TransformerFactory.newInstance();
  try {
   Transformer transformer = tf.newTransformer();
   // Transformer transformer1=tf.newTransformer(Source source);
   DOMSource source = new DOMSource(document);
   transformer.setOutputProperty(OutputKeys.ENCODING, "GBK");
   transformer.setOutputProperty(OutputKeys.INDENT, "yes");
   try {
    PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
    StreamResult result = new StreamResult(pw);
    transformer.transform(source, result);
    System.out.println("生成XML文件成功!");

   } catch (FileNotFoundException e) {
    e.printStackTrace();
    System.out.println("文件没有找到!");
   } catch (TransformerException e) {
    e.printStackTrace();
    System.out.println("生成XML文件失败!");
   }

  } catch (TransformerConfigurationException e) {
   e.printStackTrace();
  }

 }

 public void parseXml(String fileName) {
  try {
   DocumentBuilderFactory factory = DocumentBuilderFactory
     .newInstance();
   DocumentBuilder builder = factory.newDocumentBuilder();
   Document document = builder.parse(fileName);
   // 1.获得文档根元素对对象;
   Element root = document.getDocumentElement();
   // 获得文档根元素下一级子元素所有元素;
   NodeList nodeList = root.getChildNodes();
   System.out.println(root.getNodeName());
   if (null != root) {
    for (int i = 0; i < nodeList.getLength(); i++) {
     Node child = nodeList.item(i);
     // 输出child的属性;
     //System.out.println(child);
     
     if (child.getNodeType() == Node.ELEMENT_NODE) {
      System.out.println(child.getAttributes().getNamedItem(
        "email").getNodeValue());
     }

     for (Node node = child.getFirstChild(); node != null; node = node
       .getNextSibling()) {

      if (node.getNodeType() == Node.ELEMENT_NODE) {
       if ("name".equals(node.getNodeName())) {
        System.out.println(node.getFirstChild()
          .getNodeValue());
       }
      }
      if (node.getNodeType() == Node.ELEMENT_NODE) {
       if ("sex".equals(node.getNodeName())) {
        System.out.println(node.getFirstChild()
          .getNodeValue());
       }
      }
      if (node.getNodeType() == Node.ELEMENT_NODE) {
       if ("age".equals(node.getNodeName())) {
        System.out.println(node.getFirstChild()
          .getNodeValue());
       }
      }
     }
    }
   }

  } catch (ParserConfigurationException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (SAXException e) {
   e.printStackTrace();
  }

 }

 public static void main(String[] args) {
  DomXmlDemo dom = new DomXmlDemo();
   dom.createXml("F:\\employees.xml");
  dom.parseXml("F:\\employees.xml");
 }
}





结果如下:

生成XML文件成功!
employees
zzzlyr@163.com
李明
女孩子
30
zzzlyr2@163.com
张钊钊



评论

# re: Java DOM 解析 XML详解[未登录]  回复  更多评论   

2015-04-21 16:29 by 1
1

# re: Java DOM 解析 XML详解  回复  更多评论   

2015-09-20 00:57 by szm
Great!

只有注册用户登录后才能发表评论。


网站导航: