增强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<Node> 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<Node> 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 
<?xml version= "1.0" encoding= "GBK"?> 
<platscheme> 
        <schemeName/> 
        <schemeId/> 
        <platformname>1</platformname> 
        <platformId>1</platformId> 
        <updCapacity>1</updCapacity> 
        <onlineCapacity>1</onlineCapacity> 
        <delCapacity>1</delCapacity> 
        <scheme><movies><del><movie mpeg= "" moviename="" generid= "0" onlinedate=""/> 
                        </del></movies> 
        <vcom> 
  <ftpinfo> 
    <serverip>127.0.0.1</serverip> 
    <serverport>21</serverport> 
    <username>ftpnv2cds1</username> 
    <password>ftp</password> 
  </ftpinfo> 

  <webserviceinfo> 
    <serverip>127.0.0.1</serverip> 
    <serverport>8888</serverport> 
  </webserviceinfo> 

  <planinfo> 
    <!--璁″垝缂栧彿--> 
    <planid>filename</planid> 
    <downloadfile> 
      <!--闇�瑕佷笅杞界殑鏂囦欢淇℃伅--> 
      <plandata plandataid= "1" filepath= "/" filename= "filename"/> 
    </downloadfile> 
  </planinfo> 
</vcom></scheme> 
</platscheme> 
----------------------------- 
<?xml version= "1.0" encoding= "UTF-8"?> 

<platscheme>    
    <schemeName/>     
    <schemeId/>     
    <platformname>1</platformname>     
    <platformId>1</platformId>     
    <updCapacity>1</updCapacity>     
    <onlineCapacity>1</onlineCapacity>     
    <delCapacity>1</delCapacity>     
    <scheme> 
        <movies> 
            <del> 
                <movie mpeg= "" moviename="" generid= "0" onlinedate=""/>    
            </del> 
        </movies>     
        <vcom>    
            <ftpinfo>    
                <serverip>127.0.0.1</serverip>     
                <serverport>21</serverport>     
                <username>ftpnv2cds1</username>     
                <password>ftp</password>    
            </ftpinfo>     
            <webserviceinfo>    
                <serverip>127.0.0.1</serverip>     
                <serverport>8888</serverport>    
            </webserviceinfo>     
            <planinfo>    
                <!--璁″垝缂栧彿-->     
                <planid>filename</planid>     
                <downloadfile>    
                    <!--闇�瑕佷笅杞界殑鏂囦欢淇℃伅-->     
                    <plandata plandataid= "1" filepath= "/" filename= "filename"/>    
                </downloadfile>    
            </planinfo>    
        </vcom> 
    </scheme>    
</platscheme> 


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


本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/225311,如需转载请自行联系原作者
相关文章
|
XML JavaScript Java
【JAVA XML 探秘】DOM、SAX、StAX:揭秘 Java 中 XML 解析技术的终极指南!
【8月更文挑战第25天】本文详细探讨了Java中三种主流的XML解析技术:DOM、SAX与StAX。DOM将XML文档转换为树状结构,便于全方位访问和修改;SAX采取事件驱动模式,适用于大型文件的顺序处理;StAX则兼具DOM和SAX的优点,支持流式处理和随机访问。文中提供了每种技术的示例代码,帮助读者理解如何在实际项目中应用这些解析方法。
611 1
|
XML JavaScript 数据格式
XML DOM 浏览器差异
所有 modern browsers 支持 W3C DOM 规范, 但仍存在差异, 主要是处理空白和换行的不同。例如, 在 XML 中, Internet Explorer 不会将空白或换行视为文本节点, 而其他浏览器则会。这会导致相同的 XML 文档在 IE 中的子节点数为 4, 而在其他浏览器中为 9:
|
XML JavaScript 数据格式
XML DOM 浏览器差异
所有 modern browsers 支持 W3C DOM, 但在处理空白和换行上存在差异。例如, 使用记事本编辑的 XML 可能包含 CR/LF 和额外空格。IE 不将空白视作文本节点, 与其他浏览器不同。
|
XML JavaScript 数据格式
XML DOM 浏览器差异
所有 modern browsers 支持 W3C DOM, 但在处理空白和换行上存在差异。例如, 使用记事本编辑的 XML 可能包含 CR/LF 和额外空格。IE 不将空白视作文本节点, 而其他浏览器则会。这会导致对相同 XML 文档的 `childNodes` 长度计算不同: IE 显示 4 个子节点, 其他浏览器显示 9 个。
|
XML 存储 JavaScript
XML DOM - 访问节点
通过 DOM, 可全面访问 XML 文档的节点。实现这一目标有 3 种方法: 1. 使用 `getElementsByTagName()` 方法, 2. 遍历节点树, 3. 利用节点间的关联进行导航。 `getElementsByTagName()` 返回一个 Node List, 即节点数组。
|
XML JavaScript 数据格式
XML DOM 浏览器差异
输出子节点的数量。结果取决于您所使用的浏览器。IE 浏览器会输出 4(提醒 4 个子节点),而其他浏览器会输出 9(提醒 9 个子节点)。
|
XML JavaScript 数据格式
XML DOM 遍历节点树
遍历(Traverse)意味着在节点树中进行循环或移动。
|
XML Web App开发 JavaScript
XML DOM 解析器
解析器把 XML 转换为 JavaScript 可存取的对象(XML DOM)。
|
XML JavaScript 数据格式
XML DOM 遍历节点树
遍历(Traverse)意味着在节点树中进行循环或移动。
|
XML 存储 JavaScript
XML DOM - 访问节点
通过 DOM, 可全面访问 XML 文档的节点。实现这一目标有 3 种方法: - 使用 `getElementsByTagName()` 方法, - 循环遍历节点树, - 利用节点间关系进行导航。 `getElementsByTagName()` 返回一个 Node List,即一种节点数组形式。示例代码通过 `loadXMLDoc()` 函数加载 &quot;books.xml&quot; 文件到 `xmlDoc` 变量中,并随后在变量 `x` 中保存所需节点信息。

相关课程

更多