最近学习了一些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
}
}