论坛首页 入门技术论坛

用dom4j处理XML文档(CRUD)

浏览 7244 次
该帖已经被评为新手帖
作者 正文
   发表时间:2008-05-09  
[size=large]
(一)JDOM的介绍以及与JAXB的比较

Java + XML = JDOM !
这就是JDOM设计者的目标。如果你曾经使用过烦人的SAX或是DOM来处理XML,你就会知道为什么要有JDOM或者是JAXB。在今年(2002)的JavaOne会议上JDOM的主要创始人Jason Hunter有一篇精彩的演讲介绍了JDOM技术,题目就是JDOM Makes XML Easy。
在那篇文档里,JDOM被拿来与DOM比较,而我更愿意拿它同JAXB比较。因为JAXB和JDOM都是为了在Java中提供比DOM和SAX更为方便的XML处理接口而开发的,并且通过完全不同的途径来解决这个问题。JDOM的处理方式是与DOM类似的树操作。而JAXB通过DTD和绑定模式来生成访问XML文档的Java代码,将XML映射成了Java对象来操作。你可以根据项目的需要和个人喜好来决定采用哪一个。
JDOM与JAXB的比较,从本身的特点来看:
1) JDOM比JAXB更容易上手。使用JAXB首先要会编写DTD,然后还要会编写绑定模式。JDOM没有这样的要求,如果你会Java和XML,甚至可以说光是看JDOM的javadoc文档就能够使用JDOM。
2) JAXB编写好DTD和绑定模式以后,XML文档被映射成了Java对象,其数据就是Java对象的属性,连数据类型都做好了转换,因此,访问XML文档比JDOM要简便,可以说是一劳永逸。
3) JAXB由某个DTD和绑定模式生成的代码只能访问该DTD所约束的文档。如果想要访问其他XML文档,需要再编写DTD和绑定模式。JDOM可以处理任何XML文档,包括受约束的和不受约束的。

目前JDOM和JAXB都没有正式版本。JDOM的最新版本是beta8,JAXB是1.0 early access,其规范版本是0.21。相对而言,JDOM更成熟一些。例如JAXB不支持名字空间、不能向XML文档写入处理指令,有时我们需要保留的换行符和首尾空格在JAXB中自动过滤掉了,就连放在里面也不能幸免。JDOM就没有这些限制。如果说以上的3点比较是JDOM和JAXB本身的特点所决定的,几乎不可能改变,那么这里表明,JAXB还需要更多的工作。
(二)dom4j(实现了JDOM接口)对XML文件进行操作


package dom_xml;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Attribute;
import java.util.List;
import java.util.Iterator;

import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import java.io.*;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader; 
import org.dom4j.DocumentHelper;

public class XmlDom4J {
        
        /**
         * 生成xml文件;
         *
         */
        public void createXMLFile(){
                //使用 DocumentHelper 类创建一个文档实例。 DocumentHelper 是生成 XML 文档节点的 dom4j API 工厂类。
                Document document=DocumentHelper.createDocument();
                
                //使用 addElement() 方法创建根元素 catalog 。addElement() 用于向 XML 文档中增加元素。
                Element catalogElement = document.addElement("catalog");
                //在 catalog 元素中使用 addComment() 方法添加注释“An XML catalog”。
                catalogElement.addComment("An XML Catalog");
                //在 catalog 元素中使用 addProcessingInstruction() 方法增加一个处理指令。
                catalogElement.addProcessingInstruction("target","text");
                
                //在 catalog 元素中使用 addElement() 方法增加 journal 元素。
                Element journal=catalogElement.addElement("journal");
                //使用 addAttribute() 方法向 journal 元素添加 title 和 publisher 属性。
                journal.addAttribute("title", "XML Zone");
                journal.addAttribute("publisher", "IBM Devoloperment");
                
                //添加节点journal的子节点article,并设置其属性;
                Element articleElement=journal.addElement("article");
                articleElement.addAttribute("level", "Intermediate");
                articleElement.addAttribute("date", "December-2008");
                
                //添加节点articleElement的子结点title,并使用 setText() 方法设置其元素的文本。
                Element titleElement=articleElement.addElement("title");
                titleElement.setText("又是下雨天");
                
                //添加节点articleElement的子结点author.添加子结点的子结点firstname、lastname,并设置其文件;
                Element authorElement=articleElement.addElement("author");
            Element  firstNameElement=authorElement.addElement("firstname");
            firstNameElement.setText("Marcello");
            Element lastNameElement=authorElement.addElement("lastname");
            lastNameElement.setText("Vitaletti");
            
            //可以使用 addDocType()  方法添加文档类型说明。
           
            
            XMLWriter output;
                try {
                        OutputFormat format=new OutputFormat();
                        format.setEncoding("gb2312");
                        output = new XMLWriter(
                                        new FileWriter(new File("catalog.xml")),format);
                        output.write(document);
                        output.close();
                } catch (IOException e) {
                        e.printStackTrace();
                }                
        }
        
        /**
         * 修改xml文件指定节点的属性;
         * @param inputXml xml文件流
         * @oldAttributeValue 原属性;
         * @attributeValue 要修改成的值;
         * @param XPath 要修改节点属性的表达式;如:"//article/@level" 则表示修改节点level(父节点为article)的属性
         * 特别说明:@后面表示的是属性;
         */
        public Document modifyXMLNodeAttributeByName(File inputXml, String XPath,String oldAttributeValue,String attributeValue) {
                if(XPath.indexOf("@")<0){
                        System.out.println("参数XPath无效,请在要修改的属性前加入'@'");
                        return null;
                }
                SAXReader saxReader = new SAXReader();
                Document document=null;
                try {
                        document = saxReader.read(inputXml);
                        List list = document.selectNodes(XPath);
                        Iterator iter = list.iterator();
                        while (iter.hasNext()) {
                                Attribute attribute = (Attribute) iter.next();
                                if (attribute.getValue().equals(oldAttributeValue))//把原属性修改为新的属性;
                                        attribute.setValue(attributeValue);
                        }
                        
                } catch (DocumentException e) {                        
                        e.printStackTrace();
                }
                return document;
                
        }
        
        /**
         * 修改指定节点的属性值;
         * @param inputXml xml文件流
         * @param XPath 要修改节点属性的表达式;如:"//article/@level" 则表示修改节点level(父节点为article)的属性
         * @param attributeValue 属性新值;
         */
        public Document modifyXMLNodeAttributeByName(File inputXml, String XPath,String attributeValue) {
                if(XPath.indexOf("@")<0){
                        System.out.println("参数XPath无效,请在要修改的属性前加入'@'");
                        return null;
                }
                SAXReader saxReader = new SAXReader();                
                Document document=null;
                try {
                        document = saxReader.read(inputXml);                
                        List list = document.selectNodes(XPath);                        
                        Iterator iter = list.iterator();
                        while (iter.hasNext()) {
                                Attribute attribute = (Attribute) iter.next();                                
                                //把原属性修改为新的属性;
                                attribute.setValue(attributeValue);
                        }
                        
                } catch (DocumentException e) {                        
                        e.printStackTrace();
                }
                return document;
        }
        
        /**
         * 获取某一节点的属性值;
         * @param inputxml xml文件;
         * @param XPath
         * @return
         */
        public String[] getNodeAttributeValue(File inputxml,String XPath){
                String nodeAttri="";//储存节点属性值;
                if(XPath.indexOf("@")<0){
                        return null;
                }
                SAXReader saxReader=new SAXReader();
                Document document=null;
                try{
                        document=saxReader.read(inputxml);
                        List list=document.selectNodes(XPath);
                        Iterator it=list.iterator();
                        while(it.hasNext()){
                                Attribute attri=(Attribute)it.next();
                                nodeAttri+=attri.getValue()+",";
                        }
                }catch(Exception e){
                        e.printStackTrace();
                }
                if(nodeAttri.length()>0){
                        nodeAttri=nodeAttri.substring(0, nodeAttri.length()-1);
                }
                return nodeAttri.split(",");
        }
        
        /**
         * 修改指定节点的文本值;
         * @param inputXml
         * @param XPath 要修改节点属性的表达式;如:"//article/@level" 则表示article节点下的所有level节点的文本;
         * @param newText 新的文本值;
         */
        public Document modifyXMLNodeTextByName(File inputXml,String XPath,String newText){
                if(XPath.indexOf("@")>=0){
                        System.out.println("参数XPath无效!");
                        return null;
                }
                SAXReader saxReader = new SAXReader();
                Document document=null;
                try {
                        document=saxReader.read(inputXml);
                        List list= document.selectNodes(XPath);
                        Iterator iter = list.iterator();
                        while(iter.hasNext()){                                
                                Element elementText=(Element)iter.next();                                
                                elementText.setText(newText);                                
                        }
                } catch (DocumentException e) {                        
                        e.printStackTrace();
                }
                return document;
        }
        
        /**
         *  替换指定节点文本的值。
         * @param inputXml xml文件流
         * @param XPath 要修改节点属性的表达式;如:"//article/level" 则表示article节点下的所有level节点的文本;
         * @param oldText 原文本
         * @param newText 新文本;
         */
        public Document modifyXMLNodeTextByName(File inputXml,String XPath,String oldText,String newText){
                if(XPath.indexOf("@")>=0){
                        System.out.println("参数XPath无效!");
                        return null;
                }
                SAXReader saxReader = new SAXReader();
                Document document=null;
                try {
                        document=saxReader.read(inputXml);
                        List list= document.selectNodes(XPath);
                        Iterator iter = list.iterator();
                        while(iter.hasNext()){
                                Element elementText=(Element)iter.next();
                                if(elementText.getText().equals(oldText))
                                elementText.setText(newText);
                        }
                } catch (DocumentException e) {                        
                        e.printStackTrace();
                }
                return document;
        }
        /**
         * 获取某一节点的文本内容;
         * @param inputxml xml文件;
         * @param XPath
         * @return
         */
        public String[] getNodeTextValue(File inputxml,String XPath){
                String nodeTextValue="";//储存节点属性值;
                if(XPath.indexOf("@")>=0){
                        return null;
                }
                SAXReader saxReader=new SAXReader();
                Document document=null;
                try{
                        document=saxReader.read(inputxml);
                        List list=document.selectNodes(XPath);
                        Iterator it=list.iterator();
                        while(it.hasNext()){
                                Element text=(Element)it.next();
                                nodeTextValue+=text.getText()+",";
                        }
                }catch(Exception e){
                        e.printStackTrace();
                }
                if(nodeTextValue.length()>0){
                        nodeTextValue=nodeTextValue.substring(0, nodeTextValue.length()-1);
                }
                return nodeTextValue.split(",");
        }
        
        
        
        /**
         * 保存xml文件;
         * @param document xml文件流;
         * @param filePath 文件存储的全路径(包括文件名)
         * @code 储存的编码;
         */
        public void saveXmlFile(Document document,String filePath,String code){
                if(document==null){
                        return ;
                }
                XMLWriter output;
                try {
                        OutputFormat format=new OutputFormat();
                        format.setEncoding(code);
                        output = new XMLWriter(new FileWriter(new File(filePath)),format);
                        output.write( document );
                        output.close();
                } catch (IOException e) {                        
                        e.printStackTrace();
                }                
        }
                
                // 测试;
        public static void main(String[] args){
                XmlDom4J dom4jParser=new XmlDom4J();                
                //生成XML
                //dom4jParser.createXMLFile();
                File file=new File("D:/MyWork/operateXMLfile/catalog.xml");
                //dom4jParser.saveXmlFile(document, "F://test.xml", "GBK");
                
                /*String[] attrArray=dom4jParser.getNodeAttributeValue(file, "//article/@level");
                if(attrArray!=null){
                        for(int i=0;i<attrArray.length;i++){
                                System.out.println("Attribute is :"+attrArray[i]);
                        }
                }*/
                
                String[] nodeText=dom4jParser.getNodeTextValue(file, "//article/title");
                if(nodeText!=null){
                        for(int i=0;i<nodeText.length;i++){
                                System.out.println("NODE TEXT IS:"+nodeText[i]);
                        }
                }
                
        }
}



xml文件定义如下:


<?xml version="1.0" encoding="gb2312"?>
<catalog><!--An XML Catalog--><?target text?>
<journal title="XML Zone" publisher="IBM Devoloperment">
<article level="小学四年级"  date="December-2008"><title>又是下雨天</title>
<author><firstname>Marcello</firstname><lastname>Vitaletti</lastname></author></article>
<article level="大学四年级"  date="2008-04-01"><title>太阳出来了</title>
<author><firstname>Marcello</firstname><lastname>Vitaletti</lastname></author></article>
</journal></catalog>




[/size]
   发表时间:2008-05-21  
牛X ,以为是JDOM ,进来一看是写的是DOM4J。先回家搞清楚DOM4J和JDOM哦
0 请登录后投票
   发表时间:2008-06-02  
确实很牛X,我先收下了,不过我打开dom4j的官方网站,版本是1.6.1发布于May 16, 2005,为什么到现在还没有更新啊???
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics