xml的解析方式——dom/sax、jdom、dom4j

来源:互联网 发布:莱纳德 知乎 编辑:程序博客网 时间:2024/04/26 06:46

最近学习了一些xml的解析方法,本来以为面试时会被问到,现实是都没有问。而是考了一些基础的知识。我的妈啊,有些东西很久没用就忘了。废话不说,进入正题。

我知道的xml解析方式是目前比较公用的一些方式。有sun公司声称标准的jaxp(dom/sax)解析(但是自己在开发的时候是使用dom4j,不知道是什么原因??????)、jdom、dom4j。根据一些民间的传闻,这三种的解析效率是:dom4j>jdom>jaxp;本人经过学习也认为dom4j最容易掌握。现在就几种方式进行一些比较。我分别用dom、sax、jdom、dom4j来创建和读取一个xml文件.如果是大虾级以上的就不要看了,不要浪费时间了。哈哈哈。。。。。。。。。。

dom

使用dom来创建一个xml文档。

package dom;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
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 java.io.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class DOM_CreateXML {

 /**
  *功能:
  * @param args
  * @throws ParserConfigurationException
  * @throws TransformerConfigurationException
  */
 public static void main(String[] args) throws ParserConfigurationException, TransformerConfigurationException {
  /**
   * 创建一个文档构造器的工厂实例
   */
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  /**
   * 创建构造器实例
   *
   */
  DocumentBuilder builder = factory.newDocumentBuilder();
  
  /**
   * 创建存放节点的文档对象
   *
   */
  Document doc=builder.newDocument();
  
  /**
   * 定义各个操作节点
   */
  //树根
  Element tree_root=doc.createElement("tree_root");
  //树枝
  Element tree_branch=doc.createElement("tree_branch");
  //树叶
  Element tree_leave_01=doc.createElement("tree_leave_01");
  Element tree_leave_02=doc.createElement("tree_leave_02");
  //给第二个树叶节点添加一个id属性
  tree_leave_02.setAttribute("id", "first");
  /**
   * 添加节点的之间的内容
   *
   */
  tree_leave_01.setTextContent("第一片树叶");
  
  tree_leave_02.setTextContent("第二片树叶");
  
  
  /**
   * 向文档中添加节点
   */
  tree_branch.appendChild(tree_leave_01);
  tree_branch.appendChild(tree_leave_02);
  tree_root.appendChild(tree_branch);
  doc.appendChild(tree_root);
  /**
   * 把这个xml文件输出到指定的文件
   */
  //得到转换的工厂实例
  TransformerFactory transFactory=TransformerFactory.newInstance();
  //得到转换器
  Transformer former=transFactory.newTransformer();
  //设置转换器的编码
  former.setOutputProperty(OutputKeys.ENCODING,"GBK");
  
  //为了使用former.transform(xmlSource, outputTarget)来转换,需要获得Source和Result两个对象
  DOMSource source=new DOMSource(doc);
  
  Result result=new StreamResult(new File("d:"+File.separator+"tree.xml"));
  
  try {
   former.transform(source, result);
  } catch (TransformerException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
 }

}

使用domj解析方式产生的xml文件的格式是紧凑型的。我知道dom4j有格式的东西,不知道如何来格式话dom解析产生的文档?这里也请高手留言,提供一个方向。

 

用dom方式解析刚才产生的文档;

package dom;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.*;

public class DOM_ReadXML {

 /**
  *功能:
  * @param args
  * @throws ParserConfigurationException
  * @throws IOException
  * @throws SAXException
  */
 public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
  // TODO Auto-generated method stub
  /**
   * 得到解析工厂实例
   */
  DocumentBuilderFactory builderFactory= DocumentBuilderFactory.newInstance();
  /**
   * 得到解析器实例
   */
  DocumentBuilder builder=builderFactory.newDocumentBuilder();
  /**
   * 得到文本
   */
  Document doc=builder.parse(new File("d:"+File.separator+"tree.xml"));
  /**
   * 得到树枝节点数组
   */
  NodeList tree_branchs=doc.getElementsByTagName("tree_branch");
  /**
   * 获得第一个树枝节点
   */
  Element tree_branch=(Element)tree_branchs.item(0);
  /**
   * 获得该树枝节点下的叶子节点
   */
  NodeList tree_leaves=tree_branch.getChildNodes();
  
  
  for(int i=0;i<tree_leaves.getLength();i++){
   //获得节点名称
   String name=tree_leaves.item(i).getNodeName();
   //获得节点对应的文本
   String value=tree_leaves.item(i).getTextContent();
   //判断该节点是否含有属性
   if(tree_leaves.item(i).hasAttributes()){
   //获得属性的姓名,因为dom解析就是把xml中的所有东西都当作节点看待,所以用getNodeName()方法来得到标签属性名感觉有点怪。
   String attributeName=tree_leaves.item(i).getAttributes().item(0).getNodeName();
   //通过属性名来获得属性的值,这个时候要把Node类型转换为Element类型。因为Node没有getAttribute(String name)方法
   String attributeValue=(String)((Element) tree_leaves.item(i)).getAttribute(attributeName);
   System.out.println("<"+name+" "+attributeName+"="+attributeValue+">"+value+"<"+"
\\"+name+">");
   }
   else{
    System.out.println("<"+name+">"+value+"<"+"
\\"+name+">");
    
   }
  }
  
 }

}

sax 解析=解析器+事件处理器,下面是sax解析xml文档的例子

package sax;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.HandlerBase;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderAdapter;

import java.io.*;

public class sax_01 {

 
 public static void main(String args[]) throws ParserConfigurationException, SAXException, Exception{
  
  /**
   * 获得sax解析工厂实例
   */
  SAXParserFactory factory=SAXParserFactory.newInstance();
  /**
   * 通过工厂来获得解析器
   */
  SAXParser parser=factory.newSAXParser();
  
  
  /**
   * 获得读取器
   */
  XMLReader reader=parser.getXMLReader();
  
  /**
   * 设置内容处理器
   */
  reader.setContentHandler(new MyHandler());
  
  /**
   * 读取XML文件
   */
  reader.parse(new InputSource(new FileInputStream(new File("d:"+File.separator+"yangtao.xml"))));
  
 }
}
/**
 * 编写事件处理器,当sax解析到xml文本的某一部分时,sax会自动地将该部分的一些数据传给相应的方法
 *
 * @author Administrator
 *
 */
 class MyHandler extends XMLReaderAdapter{

 @Override
 public void characters(char[] ch, int start, int length)
   throws SAXException {
  // TODO Auto-generated method stub
  
  System.out.println(new String(ch,start,length).toString());
  super.characters(ch, start, length);
 }

 @Override
 public void endElement(String uri, String localName, String name)
   throws SAXException {
  // TODO Auto-generated method stub
  System.out.println("end-localName="+localName);
  System.out.println("end-Name="+name);
  super.endElement(uri, localName, name);
 }

 @Override
 public void startElement(String uri, String localName, String name,
   Attributes atts) throws SAXException {
  // TODO Auto-generated method stub
  System.out.println(uri);
  System.out.println("localName="+localName);
  System.out.println("name="+name);
  while("name".equals(name)){
   System.out.println(atts.getQName(0)+"--->"+atts.getValue(atts.getQName(0)));
   break;
  }
  super.startElement(uri, localName, name, atts);
 }

 public MyHandler() throws SAXException {
  super();
  // TODO Auto-generated constructor stub
 }
 
 
 
}

 


老婆要求加的链接>>