`
wuhongyu
  • 浏览: 404506 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

dom4j解析xml

阅读更多

    dom4j和jdom都是非常优秀的xml解析工具,但现在很多人认为dom4j无论是在性能上或是灵活性上都要优于jdom,其实,作为xml的解析工具,他们在大多情况下都能满足我们的要求。至于要选择使用哪一个,那就要依个人爱好(或是公司要求)了。

 

    以前写了一个jdom解析xml 的例子,仿照那篇,再写一个dom4j版本的。

 

    我下载的是dom4j-1.6.1.zip,解压后可以看到里面有个dom4j-1.6.1.jar,为了方便,要使用了XPath的寻址方式时,需要引入jaxen-1.1-beta-6.jar(在lib文件夹中)。引入了这两个包,就可以开始操作xml文件了。dom4j的包11M多,超过限制了,此处只把例子中用到的两个jar包传上来。

 

    dom4j-1.6.1.zip的下载地址为http://sourceforge.net/projects/dom4j/

 

    下面分别对应读、写、修改写了三个例子。

 

一、读取xml文件

 

假设有这样一个xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<sys-config>
	<jdbc-info>
		<driver-class-name>oracle.jdbc.driver.OracleDriver</driver-class-name>
		<url>jdbc:oracle:thin:@localhost:1521:database</url>
		<user-name>why</user-name>
		<password>why</password>
	</jdbc-info>
	<provinces-info>
		<province id="hlj" name="黑龙江">
			<city id="harb">哈尔滨</city>
			<city id="nj">嫩江</city>
		</province>
		<province id="jl" name="吉林"></province>
	</provinces-info>
</sys-config>

     首先,我们需要获得要解析的xml文件。dom4j提供DOMReader和SAXReader两种不同方式获取xml文件,但他们的调用方式是一样的。reader的read方法是重载的,可以从InputStream, File, Url等多种不同的源来读取,会返回一个org.dom4j.Document对象,得到的Document对象就带表了整个XML。

    然后,可以用document.getRootElement()方法来获取根节点,并从根节点开始遍历xml文档。当然,我们也可以越过此步骤,而使用XPath直接获得要操作的节点(这与jdom有一点区别,jdom需要先获得根节点才可以使用XPath方式进行遍历)。利用 document.selectNodes("nodeName") 可以取得xml中的任意制定的节点中的信息。如:

Element driverClassNameElement = (Element)document.selectSingleNode("//sys-config/jdbc-info/driver-class-name");

这样就取得了上面文件中的 <jdbc-info> 下的 <driver-class-name> 中的内容。

    如果一个节点下有多个名称相同的子节点,可以用document.selectNodes()方法取得多个子节点的List,遍历这个List就可以操作各个子节点的内容了。org.dom4j.Element对象代表每个节点。

 

下面是我写的用dom4j读取上面xml文件的例子:

package com.why.dom4j;

import java.io.File;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ReadXml {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SAXReader saxReader = new SAXReader();
		try {
			Document document = saxReader.read(new File("src/config.xml"));
//			Element rootEle = document.getRootElement();//获取根节点
			
			Element driverClassNameElement = (Element)document.selectSingleNode("//sys-config/jdbc-info/driver-class-name");
            String driverClassName = driverClassNameElement.getText();
            System.out.println("driverClassName = " + driverClassName);

            List provinceList = document.selectNodes("//sys-config/provinces-info/province");
            for(Iterator it = provinceList.iterator();it.hasNext();){
                Element provinceEle = (Element)it.next();
                String proId = provinceEle.attributeValue("id");
                String proName = provinceEle.attributeValue("name");
  
                System.out.println("provinceId = " + proId + "   provinceName = " + proName);
                   
                List cityEleList = (List)provinceEle.elements("city");
                   
                for(Iterator cityIt = cityEleList.iterator();cityIt.hasNext();){
                    Element cityEle = (Element)cityIt.next();
                    String cityId = cityEle.attributeValue("id");
                    String cityName = cityEle.getText();
  
                    System.out.println("    cityId = " + cityId + "   cityName = " + cityName);
                }
            }
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}

}

 

  二、写xml文件

 

    首先,用DocumentHelper.createDocument()方法创建一个Document对象,并调用document.addElement()来创建一个根节点。

    然后,用Element的addElement()为一个节点添加子节点,addAttribute()方法添加属性。

    构造完xml文档结构后,使用org.dom4j.io.XMLWriter的write()方法,将构造好的文档输出到指定位置,当然,可以用org.dom4j.io.OutputFormat对生成的文档进行美化。

 

代码如下:

package com.why.dom4j;

import java.io.FileWriter;
import java.io.IOException;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;


public class WriteXML {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Document document = DocumentHelper.createDocument();
		Element root = document.addElement("sys-config");
		
		Element provinceEle = 
			root.addElement("provinces-info")
			.addElement("province")
			.addAttribute("id","hlj")
			.addAttribute("name","黑龙江省");
		
		Element cityEle1 = provinceEle.addElement("city");
		cityEle1.addAttribute("id","harb");
		cityEle1.addText("哈尔滨");
		
		Element cityEle2 = 
			provinceEle.addElement("city")
			.addAttribute("id","nj")
			.addText("嫩江");
		
//		OutputFormat format = OutputFormat.createPrettyPrint();// 美化格式
		OutputFormat format = OutputFormat.createCompactFormat();// 缩减格式
//      format.setEncoding("UTF-8");// 设置编码格式
        format.setIndent("    "); //缩进4个空格后换行
        
        XMLWriter writer;
		try {
			writer = new XMLWriter(new FileWriter("src/output.xml"), format);
			writer.write(document);
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
        
		String xmlStr = document.asXML();
		System.out.println(xmlStr);
		
		// 也可以将字符串转XML
//		String text = "<sys-config><provinces-info><province>黑龙江省</province></provinces-info></sys-config>";
//		Document document = DocumentHelper.parseText(text);
	}

}

 

三、修改xml文件

 

    以上面的xml为例,现进行三项修改:

    1、在<province id="jl" name="吉林"></province>之间添加一个子节点<city id="jls">吉林市</city>:

    首先取得id="jl"的province节点,然后调用addElement()方法添加子节点,与写文件操作相同,如:

province.addElement("city").addAttribute("id", "jls").addText("吉林市");

    2、将<city id="harb">哈尔滨</city>的id属性改为“HaErBin”,内容改为“哈尔滨市”:

    遍历所有的city节点,并取得其“id”属性:Attribute attribute = (Attribute)city.attribute("id");

若其“id”属性的值为“harb”,则调用其attribute属性的setValue()方法:attribute.setValue("HaErBin");并调用该city节点的setText()方法将其内容改为“哈尔滨市”。

    3、删除<city id="nj">嫩江</city>节点:

    取得id="nj"的city节点,并调用其父节点的remove()方法删除此节点:city.getParent().remove(city);

 

代码如下:

package com.why.dom4j;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class ModifyXml {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SAXReader saxReader = new SAXReader();
		File file = new File("src/config.xml");
			try {
				Document document = saxReader.read(file);
				
				List provinceList = (List)document.selectNodes("//sys-config/provinces-info/province");
				for(Iterator it = provinceList.iterator();it.hasNext();){
					Element province = (Element)it.next();
					Attribute attribute = (Attribute)province.attribute("id");
					System.out.println(attribute.getValue());
					if(attribute.getValue().equals("jl")){
						System.out.println(province.getText());
						province.addElement("city")
						.addAttribute("id", "jls").addText("吉林市");
					}
				}
				
				List cityList = (List)document.selectNodes("//sys-config/provinces-info/province/city");
				for(Iterator it = cityList.iterator();it.hasNext();){
					Element city = (Element)it.next();
					Attribute attribute = (Attribute)city.attribute("id");
					System.out.println(attribute.getValue());
					if(attribute.getValue().equals("harb")){
						attribute.setValue("HaErBin");
						System.out.println(city.getText());
						city.setText("哈尔滨市");
					}
					if(attribute.getValue().equals("nj")){
						city.getParent().remove(city);
					}
				}
				
				OutputFormat format = OutputFormat.createPrettyPrint();
				format.setEncoding("UTF-8");// 设置编码格式
				format.setIndent("    "); //缩进4个空格后换行
				XMLWriter writer = new XMLWriter(new FileOutputStream(file),format);
				writer.write(document);
				writer.close();
			} catch (DocumentException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

	}

}
 

 

 

Invalid byte 1 of 1-byte UTF-8 sequence的解决办法:

将new XMLWriter(new FileWriter("src/output.xml"), format);改为:

   new XMLWriter(new FileOutputStream("src/output.xml"), format);

 

为避免程序中出现中文乱码问题,也可以将xml文件以及程序中设置的编码格式统一改为GBK,有关中文乱码的问题,可以参考http://kevin-qingzhan.iteye.com/blog/473994

 

 

 

分享到:
评论
1 楼 lightdows 2013-10-14  
[b][/b]

相关推荐

Global site tag (gtag.js) - Google Analytics