增强Dom4j--让XML处理更容易
 
Java处理XML的工具包中,Dom4j是佼佼者,但是使用起来还是不够简洁。
为更方便使用Dom4j处理XML,这里做了一些工具类库,放出来以供参考。
 
一、文件与字符串相互转换的工具
处理XML文件读取的问题,实际上这个是一个文本文件读取的问题。
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;

/**
* 字符串与文件相互转换工具
*
* @author leizhimin 2009-11-11 15:54:18
*/

public class StringFileToolkit {
         private static Log log = LogFactory.getLog(StringFileToolkit. class);

         /**
         * 读取输入流为一个内存字符串,保持文件原有的换行格式
         *
         * @param in            输入流
         * @param charset 文件字符集编码
         * @return 文件内容的字符串
         */

         public static String file2String(InputStream in, String charset) {
                StringBuffer sb = new StringBuffer();
                 try {
                        LineNumberReader reader = new LineNumberReader( new BufferedReader( new InputStreamReader(in, charset)));
                        String line;
                         while ((line = reader.readLine()) != null) {
                                sb.append(line).append(System.getProperty( "line.separator"));
                        }
                        reader.close();
                } catch (UnsupportedEncodingException e) {
                        log.error( "读取文件为一个内存字符串失败,失败原因是使用了不支持的字符编码" + charset, e);
                } catch (IOException e) {
                        log.error( "读取文件为一个内存字符串失败,失败原因是读取文件异常!", e);
                }
                 return sb.toString();
        }

         /**
         * 读取文件为一个内存字符串,保持文件原有的换行格式
         *
         * @param file        文件对象
         * @param charset 文件字符集编码
         * @return 文件内容的字符串
         */

         public static String file2String(File file, String charset) {
                StringBuffer sb = new StringBuffer();
                 try {
                        LineNumberReader reader = new LineNumberReader( new BufferedReader( new InputStreamReader( new FileInputStream(file), charset)));
                        String line;
                         while ((line = reader.readLine()) != null) {
                                sb.append(line).append(System.getProperty( "line.separator"));
                        }
                        reader.close();
                } catch (UnsupportedEncodingException e) {
                        log.error( "读取文件为一个内存字符串失败,失败原因是使用了不支持的字符编码" + charset, e);
                } catch (FileNotFoundException e) {
                        log.error( "读取文件为一个内存字符串失败,失败原因所给的文件" + file + "不存在!", e);
                } catch (IOException e) {
                        log.error( "读取文件为一个内存字符串失败,失败原因是读取文件异常!", e);
                }
                 return sb.toString();
        }

         /**
         * 将字符串存储为一个文件,当文件不存在时候,自动创建该文件,当文件已存在时候,重写文件的内容,特定情况下,还与操作系统的权限有关。
         *
         * @param text         字符串
         * @param distFile 存储的目标文件
         * @return 当存储正确无误时返回true,否则返回false
         */

         public static boolean string2File(String text, File distFile) {
                 if (!distFile.getParentFile().exists()) distFile.getParentFile().mkdirs();
                BufferedReader br = null;
                BufferedWriter bw = null;
                 boolean flag = true;
                 try {
                        br = new BufferedReader( new StringReader(text));
                        bw = new BufferedWriter( new FileWriter(distFile));
                         char buf[] = new char[1024 * 64];         //字符缓冲区
                         int len;
                         while ((len = br.read(buf)) != -1) {
                                bw.write(buf, 0, len);
                        }
                        bw.flush();
                        br.close();
                        bw.close();
                } catch (IOException e) {
                        flag = false;
                        log.error( "将字符串写入文件发生异常!", e);
                }
                 return flag;
        }

         public static void main(String[] args) {
                String x = file2String( new File( "C:\\a.txt"), "GBK");
                System.out.println(x);

                 boolean b = string2File(x, new File( "C:\\b.txt"));
                System.out.println(b);
        }
}
 
二、Doc文档的一些常用操作
 
构建Document文档对象,删除、添加XML元素,格式化XML。
 
package zzvcom.common;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.List;

/**
* XML便捷工具箱
*
* @author leizhimin 2009-11-11 16:26:19
*/

public class XmlToolkit {
         private static Log log = LogFactory.getLog(XmlToolkit. class);


         /**
         * 根据classpath下xml文件名创建一个XML文档对象,并制定读取字符集
         *
         * @param classPathFileName xml文件名称,
         * @param charset                     xml文件字符集编码
         * @return xml的字符串
         */

         public static Document makeDocument(String classPathFileName, String charset) {
                Document doc = null;
                 try {
                        InputStream in = XmlToolkit. class.getClassLoader().getResourceAsStream(classPathFileName);
                        String xml = StringFileToolkit.stream2String(in, charset);
                        doc = DocumentHelper.parseText(xml);
                } catch (Exception e) {
                        log.error( "解析XML发生错误,请检查ClassPath下面的" + classPathFileName + "文件是否存在,格式是否是正确!");
                         throw new RuntimeException(e);
                }
                 return doc;
        }

         /**
         * 创建一个XML文档对象
         *
         * @param xmlfile xml文件
         * @param charset xml文件字符集编码
         * @return xml的字符串
         */

         public static Document makeDocument(File xmlfile, String charset) {
                Document doc = null;
                 try {
                        String xml = StringFileToolkit.file2String(xmlfile, charset);
                        doc = DocumentHelper.parseText(xml);
                } catch (Exception e) {
                        log.error( "解析XML发生错误,请检查" + xmlfile.getPath() + "文件是否存在,格式是否是正确!");
                         throw new RuntimeException(e);
                }
                 return doc;
        }

         /**
         * 删除文档doc的指定路径下的所有子节点(包含元素,属性等)
         *
         * @param doc     文档对象
         * @param xpath 指定元素的路径
         * @return 删除成功时返回true,否则false
         */

         public static boolean deleteNodes(Document doc, String xpath) {
                 boolean flag = true;
                 try {
                        List nlist = doc.selectNodes(xpath);
                         for (Node node : nlist) {
                                node.detach();
                        }
                } catch (Exception e) {
                        flag = false;
                }
                 return flag;
        }

         /**
         * 删除一个父元素下所有的子节点(包含元素,属性等)
         *
         * @param element 父元素
         * @return 删除成功时返回true,否则false
         */

         public static boolean deleteChildren(Element element) {
                 boolean flag = true;
                 try {
                        List nlist = element.elements();
                         for (Node node : nlist) {
                                node.detach();
                        }
                } catch (Exception e) {
                        flag = false;
                }
                 return flag;
        }

         /**
         * 在指定文档doc的xpath元素下面添加ename子元素,并给出子元素的text值
         *
         * @param doc        文档对象
         * @param xpath    父元素的xpath
         * @param ename    所加入子元素名称
         * @param evalue 所加入子元素的text值
         * @return 加入后的xml元素
         */

         public static Element addElement(Document doc, String xpath, String ename, String evalue) {
                Element element = null;
                Node n = (Node) doc.selectSingleNode(xpath);
                 if (n instanceof Element) {
                        Element e = (Element) n;
                        element = e.addElement(ename);
                        element.setText(evalue);
                }
                 return element;
        }

         /**
         * 在指定文档doc的xpath元素下面添加xml文档为子元素
         *
         * @param doc     文档对象
         * @param xpath 父元素的xpath
         * @param xml     要加入的xml文档
         * @return 所加入后的xml元素
         */

         public static Element addElementByString(Document doc, String xpath, String xml) {
                Element subdoc = null;
                 try {
                        subdoc = DocumentHelper.parseText(xml).getRootElement();
                } catch (DocumentException e) {
                        e.printStackTrace();
                }
                Node n = (Node) doc.selectSingleNode(xpath);
                 if (n instanceof Element) {
                        Element e = (Element) n;
                        e.add(subdoc);
                        System.out.println(subdoc.getPath());
                }
                 return subdoc;
        }

         /**
         * 格式化XML文档
         *
         * @param document xml文档
         * @param charset    字符串的编码
         * @return 格式化后XML字符串
         */

         public static String formatXML(Document document, String charset) {
                OutputFormat format = OutputFormat.createPrettyPrint();
                format.setEncoding(charset);
                StringWriter sw = new StringWriter();
                XMLWriter xw = new XMLWriter(sw, format);
                 try {
                        xw.write(document);
                        xw.flush();
                        xw.close();
                } catch (IOException e) {
                        log.error( "格式化XML文档发生异常,请检查!", e);
                }
                 return sw.toString();
        }
}
 
 
测试输出结果:
/platscheme/scheme/vcom
"1.0" encoding= "GBK"?>

        
        
        1
        1
        1
        1
        1
        "" moviename="" generid= "0" onlinedate=""/>
                        

        
  
    127.0.0.1
    21
    ftpnv2cds1
    ftp
  


  
    127.0.0.1
    8888
  


  
    
    filename
    
      
      "1" filepath= "/" filename= "filename"/>
    

  



-----------------------------
"1.0" encoding= "UTF-8"?>

    
        
        
    1    
    1    
    1    
    1    
    1    
    
        
            
                "" moviename="" generid= "0" onlinedate=""/>    
            

        
    
            
                
                127.0.0.1    
                21    
                ftpnv2cds1    
                ftp    
            
    
                
                127.0.0.1    
                8888    
            
    
                
                    
                filename    
                    
                        
                    "1" filepath= "/" filename= "filename"/>    
                
    
            
    
        

    
    



Process finished with exit code 0
 
有了以上的扩展,结合Dom4j,处理XML的工作会变得相当轻松容易。