Java操作XML文件
一.下载Dom4j.jar包,复制至exjar文件夹中,并通过eclipse的building Path选项,配置class路径。
1.创建一个xml文件
假如我们需要创建如下的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<website>
<!--about my blog-->
<domain type="blog">
<url>hrmzone.cn</url>
<catalog>computer</catalog>
</domain>
<author>hrmzone</author>
<createdate>2009</createdate>
</website>
创建一个java源文件,命名为CreateXML.java,内容如下:
package cn.hrmzone.xml;
import java.io.File;
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;
import org.junit.Test;
/**
* <p>2010-9-19</p>
* @author <b>hrmzone.cn</b>
*
*/
public class CreateXML {
/**
*
* @return 测试方法,无返回值
*
*/
@Test
public void testCreate() {
// TODO Auto-generated method stub
Document document=DocumentHelper.createDocument();
Element siteElement=document.addElement("website");
siteElement.addComment("about my blog");
Element domainElement=siteElement.addElement("domain");
domainElement.addAttribute("type", "blog");
Element urlElement=domainElement.addElement("url");
urlElement.setText("hrmzone.cn");
Element catalogElement=domainElement.addElement("catalog");
catalogElement.setText("computer");
Element authorElement=siteElement.addElement("author");
authorElement.setText("hrmzone");
Element dateElement=siteElement.addElement("date");
dateElement.setText("2009");
OutputFormat format=OutputFormat.createPrettyPrint();
try {
XMLWriter output=new XMLWriter(new FileWriter(new File("output\\test.xml")),format);
output.write(document);
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这里用到junit类进行测试,运行后,会在项目下的output文件夹中产生一个test.xml文件,打开之后会发现和之前需要创建的文件一致。现在对xml文件的创建进行说明:
创建一个xml文档的实例,DomcutmentHelper是生成xml文档节点的工厂类:
Document document=DocumentHelper.createDocument();
createDocument():是一个静态方法。
为创建的文档添加元素:
Element siteElement=document.addElement("website");
addElement:添加元素,其对象如果Document就是添加根元素,其对象如果是Element,那么就是添加子元素;
为根元素添加一个注释“about my blog”:
siteElement.addComment("about my blog");
同时为根元素添加子元素:domain、author、date
Element domainElement=siteElement.addElement("domain");Element authorElement=siteElement.addElement("author");Element dateElement=siteElement.addElement("date");
现在我想为domain元素添加一个属性:type,表面我网站的类型是blog:
domainElement.addAttribute("type", "blog");
Element.addAttribute():此方法为元素添加属性,内有两个参数,分别表示属性名称和值;
添加子元素的方法是一致,不论层次有多少,都是在上层元素上使用AddElement方法。
如果我需要为元素添加CDATA元素,就是字符元素,为computer、author、date三个元素添加文本:
catalogElement.setText("computer");authorElement.setText("hrmzone");dateElement.setText("2009");
Element.setText():为元素增加文本
至此为止,已经将xml的元素和内容建立,接下来需要将其保存到test.xml文件中。创建一个XMLWriter对象,其参数FileWriter类型,如果这样直接保存的话,产生的xml文件是一种紧凑型,就是说所有的元素、内容均在一行,如果需要产生层次分明的文档,需要创建一个OutputFormat对象,并作为参数加入到XMLWriter中:
OutputFormat format=OutputFormat.createPrettyPrint();
try {
XMLWriter output=new XMLWriter(new FileWriter(new File(”output\\test.xml”)),format);
output.write(document);
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
注意:在结束时应关闭XMLWriter。
二.读取xml文档
1.读取xml文档
xml文档的也是一个文件,所以读取一个xml文件和读取一个其他的普通文件是一样的,需要先创建一个File,指定将被读取的文件。在创建一个xml文件时,是使用DocumentHelper类,注意,读取则不一样,是使用SAXReader类。如:
/**
*
*/
package cn.hrmzone.xml;
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;
/**
* @author hrmzone.cn
*2010-9-19
*/
public class ReaderXML {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
File file=new File("output\\test.xml");
SAXReader reader=new SAXReader();
try {
Document doc=reader.read(file);
Element root=doc.getRootElement();
for(Iterator iter=root.elementIterator();iter.hasNext();) {
Element element=(Element) iter.next();
System.out.println(element.getName()+"\t:"+element.getStringValue());
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
System.out.println("有异常抛出");
e.printStackTrace();
}
}
}
解释过程:
根据文件名创建一个File
File file=new File("output\\test.xml");
创建一个SAXReader实例,他可以用来读取文件
SAXReader reader=new SAXReader();
通过SAXReader的reader方法读取文件:
Document doc=reader.read(file);
载入文件之后,就可以对xml的元素、属性等进行读取了,for循环语句即为获取所有元素节点的元素名称和属性值
for(Iterator iter=root.elementIterator();iter.hasNext();) {
Element element=(Element) iter.next();
System.out.println(element.getName()+"\t:"+element.getStringValue());
}
2.读取xml文档中的元素、属性
以上的循环只能从根节点通过迭代的方式,逐渐来访问其子节点和属性,那么,如果需要直接访问某个节点或者某个已知名称的属性呢,有没有快捷的方法呢。毫无疑问,当然有这种便捷方式来,就是通过XPath来访问指定的元素、属性,如下代码:
/**
*
*/
package cn.hrmzone.xml;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.junit.Before;
import org.junit.Test;
/**
* @author hrmzone.cn
*2010-9-26
*/
public class XMLTest {
File file;
Document doc;
OutputFormat format;
Logger logger;
@Before
public void init() {
file=new File("output\\test.xml");
format=OutputFormat.createPrettyPrint();
logger=Logger.getLogger(XMLTest.class);
DOMConfigurator.configure("bin\\cn\\hrmzone\\xml\\Log4J.xml");
}
@Test
public void testRead() {
logger.debug("test starting");
try {
doc=new SAXReader().read(file);
Element root=doc.getRootElement();
// 选取所有匹配domain的元素,而不考虑domain的位置所在
List<Element> l1=doc.selectNodes("//domain/url");
for(Iterator<Element> iter=l1.iterator();iter.hasNext();) {
Element e=iter.next();
System.out.println(e.getName());
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
System.out.println("无法加载文件");
e.printStackTrace();
}
}
}
输出结果为url,即输出匹配的domain的子元素url的元素名。(这个测试类中使用了Log4j的相关知识,如果不了解Log4j,可以删除相关的内容,可以正常执行。
//:表示从当前元素节点开始搜索,知道匹配
List<Element> l1=doc.selectNodes("//domain/url");
XPath另有很多表达式,介绍几个可以常用的:
@:表示选取元素的属性,如“//domain/@type”,即需找名为domain,属性为type的属性。
/:从根节点开始选取,如:“/weisite/author”,从根节点开始需找。
仅为元素名:选取所有此元素名的子节点,如“domain”,选取了url,catalog节点。
XPath还有很多强大的表达式,这里就不一一介绍。
强调一点,XPath需要导入另外一个jar包,而不仅仅在class path中导入dom4j就行了。这个jar包在下载的dom4j的lib目录下,包名为:jaxen-1.1-beta-6,如果没有导入此包,使用XPath是会报异常,如下:
Exception in thread "main" java.lang.NoClassDefFoundError: org/jaxen/JaxenException
ok,读取、创建xml文档就是这么简单。
