dom4j xml文件读写

 

本文档包含四个部分:

<!-- [if !supportLists]-->Ø        <!-- [endif]-->写 XML 示例

<!-- [if !supportLists]-->Ø        <!-- [endif]-->修改 XML

<!-- [if !supportLists]-->Ø        <!-- [endif]-->读 XML 示例

<!-- [if !supportLists]-->Ø        <!-- [endif]-->任务描述:使用递归 , 完成对任何 xml 文件的读取

 

 

写文件示例:

/**

  任务描述:使用JAVA 程序输出下面的xml 文档:class.xml

 

    <?xml version="1.0" encoding="GBK"?>

   

    <root year="2008">

      <boss> 带头大哥 </boss>

      <class id="01" teacher=" 张三"> 一班 </class>

      <class id="02" teacher=" 李四"> 二班 </class>

      <class id="03" teacher=" 张三丰"> 三班 </class>

    </root>

  */

package chapter12.dom4j;

 

import java.io.FileWriter;

import org.dom4j.Document;

import org.dom4j.DocumentHelper;

import org.dom4j.Element;

import org.dom4j.io.OutputFormat;

import org.dom4j.io.XMLWriter;

 

public class WriteDemo {

 

    public static void main(String[] args) throws Exception {

        // 创建文档对象

        Document doc = DocumentHelper.createDocument ();

       

        // 创建根节点 <lovo></lovo>

        Element root = doc.addElement( "root" );

       

        // 增加属性节点  <root year="2008"></root>

        root.addAttribute( "year" , "2008" );

        root.addElement( "boss" ).addText( " 带头大哥" );

       

        // 增加带属性和文本的子节点  <class id="01" teacher=" 张三"> 一班</class>

        root.addElement( "class" ).addAttribute( "id" , "01" ).addAttribute( "teacher" , " 张三" ).addText( " 一班" );

        root.addElement( "class" ).addAttribute( "id" , "02" ).addAttribute( "teacher" , " 李四" ).addText( " 二班" );

        root.addElement( "class" ).addAttribute( "id" , "03" ).addAttribute( "teacher" , " 张三丰" ).addText( " 三班" );

       

        // 保存( 指定编码)

        FileWriter out1 = new FileWriter( "class.xml" );

       

       

        OutputFormat format = OutputFormat.createPrettyPrint (); //createCompactFormat,createPrettyPrint

        format.setEncoding( "GBK" ); 

       

        XMLWriter  out2 = new XMLWriter(out1,format); // 指定格式

       

        out2.write(doc);

        out2.close();

    }

   

}

 

修改文件示例:

/**

  * 任务描述:将下面class.xmlid=02 的节点中的文本改为“项目二部”,teacher 改为“带头大哥”

   <?xml version="1.0" encoding="GBK"?>

    <root year="2008">

      <boss> 带头大哥 </boss>  

      <class id="01" teacher=" 张三"> 一班 </class>  

      <class id="02" teacher=" 李四"> 二班 </class>  

      <class id="03" teacher=" 张三丰"> 三班 </class>

    </root>

  */

package chapter12.dom4j;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.FileWriter;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.util.List;

 

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 ModifyDemo {

 

   

    public static void main(String[] args) throws Exception {

        StringBuffer sb = new StringBuffer();

 

        SAXReader reader = new SAXReader();

 

        // 得到文档对象

        Document doc = null ;

        try {

            // 指定编码, 避免出现

            InputStream isr = new FileInputStream ( new File ( "class.xml" ));

            doc = reader.read( new InputStreamReader(isr, "GBK" ));

            isr.close();

        } catch (DocumentException e) {

            e.printStackTrace();

        }

 

          // 使用XPATH 表达式获得节点列表

        List<Element> list = doc.selectNodes( "//root/class" );

        // 创建一个迭代器.

        for (Element ele:list){

        String id = ele.valueOf( "@id" );

       

        if (id!= null && id.equals( "02" )){

             ele.setText( " 项目二部" );

             ele.setAttributeValue( "teacher" , " 带头大哥" );

        }

        }

       

        // 保存( 指定编码)

        FileWriter out1 = new FileWriter( "class.xml" );

       

        OutputFormat format = OutputFormat.createPrettyPrint ();

        format.setEncoding( "GBK" ); 

       

        XMLWriter  out2 = new XMLWriter(out1,format); // 指定格式

       

        out2.write(doc);

        out2.close();       

    }

}

 

读文件示例:

/**

  * 读取class.xml, 内容如下:

    <?xml version="1.0" encoding="GBK"?>

    <root year="2008">

      <boss> 带头大哥 </boss>

      <class id="01" teacher=" 张三"> 一班 </class>

      <class id="02" teacher=" 李四"> 二班 </class>

      <class id="03" teacher=" 张三丰"> 三班 </class>

    </root>

   

** 要求输出以下内容:

    根节点:root

    class= 一班   id = 01   teacher = 张三 year=2008

    class= 二班   id = 02   teacher = 李四 year=2008

    class= 三班   id = 03   teacher = 张三丰 year=2008

   

    teacher= 张三

    teacher= 李四

    teacher= 张三丰

  */

 

package chapter12.dom4j;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.util.List;

 

import org.dom4j.Attribute;

import org.dom4j.Document;

import org.dom4j.DocumentException;

import org.dom4j.Element;

import org.dom4j.io.SAXReader;

 

public class ReadDemo {

 

    public static void main(String[] args) throws Exception {

        StringBuffer sb = new StringBuffer();

 

        SAXReader reader = new SAXReader();

 

        // 得到文档对象

        Document doc = null ;

        try {

            // 指定编码, 避免出现

            InputStream isr = new FileInputStream ( new File ( "class.xml" ));

            doc = reader.read( new InputStreamReader(isr, "GBK" ));

            isr.close();

        } catch (DocumentException e) {

            e.printStackTrace();

        }

 

        // 获取根节点

        Element eleRoot = doc.getRootElement();

        System. out .println( " 根节点:" +eleRoot.getName());

       

        // 获取指定路径中的( 多个) 节点

        List<Element> listClass = doc.selectNodes( "//root/class" );

        for ( int i = 0; i < listClass.size(); i++) {

            // 获取当前节点

            Element ele = listClass.get(i);

           

            // 获取当前节点的 名称和文本

            sb.append(ele.getName() + "=" + ele.getText());

           

            // 获取属性值

            sb.append( "  id = " +ele.valueOf( "@id" ));

            sb.append( "  teacher = " +ele.valueOf( "@teacher" ));

           

            // 获取父节点 ( 文本、属性……)

            sb.append( " year" + "=" + ele.getParent().valueOf( "@year" )+ " \r" );

        }

       

        System. out .println(sb.toString());

       

        // 演示:获取指定路径中的( 多个) 属性

        List<Attribute> list = doc.selectNodes( "//root/class/@teacher" );       

//      for(int i=0;i<list.size();i++){

//          Attribute att = list.get(i);

//          System.out.println(att.getName()+"="+att.getValue());

//      }

       

        // 使用JDK1.5 中的for each 循环完成上面代码的功能( 对比学习)

       

        for (Attribute att:list){

            System. out .println(att.getName()+ "=" +att.getValue());          

        }

 

    }

 

}

 

递归读示例:

/**
 * 任务描述:使用递归,完成对任何xml文件的读取
 */
package xml.dom4j;

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

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

public class ReadDiGui {

    public static void main(String[] args) {
        ReadDiGui dr = new ReadDiGui();
        dr.prinatAllNode();
    }

    public void prinatAllNode() {
        SAXReader reader = new SAXReader();

        // 得到文档对象
        Document doc = null;
        try {
            doc = reader.read(new File("class.xml"));
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        // 得到根节点
        Element root = doc.getRootElement();

        // 循环所有节点
        printAllChildNode(root);
    }
   
    /**
     * 打印所有子节点
     */
    public void printAllChildNode(Element element) {
        // 循环当前节点的所有属性
        Iterator j =  element.attributeIterator();
        while (j.hasNext()) {
            Attribute attribute = (Attribute) j.next();
            System.out.println("    "
                    +attribute.getName()
                    + " = "
                    + attribute.getText());
        }
       
        for (int i = 0, size = element.nodeCount(); i < size; i++) {
            Node node = element.node(i);
            if (node instanceof Element) {
                System.out.println(
                        node.getName()
                        + " = "
                        + node.getText());
               
                printAllChildNode((Element) node);//自己调用自己--递归
            }
        }
    }   
}
===========================

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。 http://lavasoft.blog.51cto.com/62575/347348
<!-- 正文 begin-->
Dom4j格式化转义字符问题
 
1、不得不说的XML CDATA部件
 
在XML文档中的所有文本都会被解析器解析。
 
只有在CDATA部件之内的文本会被解析器忽略。
 
不合法的XML字符必须被替换为相应的实体。
 
如果在XML文档中使用类似"<" 的字符, 那么解析器将会出现错误,因为解析器会认为这是一个新元素的开始。
 
&lt; < 小于号
&gt; > 大于号
&amp; &
&apos; ' 单引号
&quot; " 双引号

实体必须以符号"&"开头,以符号";"结尾。
注意: 只有"<" 字符和"&"字符对于XML来说是严格禁止使用的。剩下的都是合法的,为了减少出错,使用实体是一个好习惯。

CDATA部件
在CDATA内部的所有内容都会被解析器忽略。
如果文本包含了很多的"<"字符和"&"字符——就象程序代码一样,那么最好把他们都放到CDATA部件中。
一个 CDATA 部件以"<![CDATA[" 标记开始,以"]]>"标记结束:

CDATA注意事项:
CDATA部件之间不能再包含CDATA部件(不能嵌套)。如果 CDATA部件包含了字符"]]>" 或者"<![CDATA[" ,将很有可能出错哦。
同样要注意在字符串"]]>"之间没有空格或者换行符。
 
2、Dom4j格式化转义字符问题
 
person.xml
<? xml version ="1.0" encoding ="UTF-8" ?>
< person >
         < name > 张三 </ name >
         < addr > <![CDATA[经三路 < 鑫苑 > 19F]]> </ addr >
</ person >
 
上面的XML在被Dom4j格式化的时候,自动会被转义,转义后的内容如下:
<?xml version="1.0" encoding="GBK"?>
<person>
  <toname>&lt;![CDATA[经三路&lt;鑫 苑&gt;19F]]&gt;</toname>
</person>
 
这样,显然不是想要的结果,因为CDATA不需要再转义了。如何处理该问题,看下面的程序的处理:
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.IOException;
import java.io.StringWriter;
import java.util.Date;

/**
* Created by IntelliJ IDEA.
*
* @author leizhimin 2010-7-10 16:03:39
*/

public class Person {
         private String name;
         private String addr;

         public Person(String name, String addr) {
                 this .name = name;
                 this .addr = addr;
        }

         public static void main(String[] args) {
                Person p = new Person( "张三" , "经三路<鑫苑>19F" );
                p.showXml();
        }

         public void showXml() {
                String xml1, xml2, xml3;
                Document doc = DocumentHelper.createDocument();
                doc.setXMLEncoding( "GBK" );
                Element root = doc.addElement( "person" );
                 if (addr != null )
                        addElement(root, "toname" , "<![CDATA[" + this .addr + "]]>" );
                 else
                        addElement(root, "toname" , this .addr);

                xml1 = doc.asXML();                                         //默认转义
                xml2 = formatXml(doc, "GBK" , true );         //转义
                xml3 = formatXml(doc, "GBK" , false );     //不转义
                System.out.println(xml1);
                System.out.println( "-------------------------" );
                System.out.println(xml2);
                System.out.println( "-------------------------" );
                System.out.println(xml3);
        }

         /**
         * 在指定的元素下添加一个新的子元素
         *
         * @param e         父元素
         * @param name    子元素名
         * @param value 子元素值
         * @return 新加子元素
         */

         public static Element addElement(Element e, String name, Object value) {
                Element x = e.addElement(name);
                 if (value == null || "".equals(value.toString().trim())) {
                        x.setText("");
                } else if (value instanceof Date) {
                        x.setText(DateToolkit.toISOFormat((Date) value));
                } else {
                        x.setText(value.toString());
                }
                 return x;
        }

         /**
         * 格式化XML文档
         *
         * @param document xml文档
         * @param charset    字符串的编码
         * @param istrans    是否对属性和元素值进行转移
         * @return 格式化后XML字符串
         */

         public static String formatXml(Document document, String charset, boolean istrans) {
                OutputFormat format = OutputFormat.createPrettyPrint();
                format.setEncoding(charset);
                StringWriter sw = new StringWriter();
                XMLWriter xw = new XMLWriter(sw, format);
                 xw.setEscapeText(istrans);
                 try {
                        xw.write(document);
                        xw.flush();
                        xw.close();
                } catch (IOException e) {
                        System.out.println( "格式化XML文档发生异常,请检查!" );
                        e.printStackTrace();
                }
                 return sw.toString();
        }
}
 
输出结果:
<?xml version="1.0" encoding="GBK"?>
<person><toname>&lt;! [CDATA[经三路&lt;鑫苑&gt;19F]]&gt;</toname></person>
-------------------------
<?xml version="1.0" encoding="GBK"?>
<person>
  <toname>&lt;![CDATA[经三路&lt;鑫 苑&gt;19F]]&gt;</toname>
</person>
-------------------------
<?xml version="1.0" encoding="GBK"?>
<person>
  <toname><![CDATA[经三路<鑫苑>19F]]></toname>
</person>

Process finished with exit code 0
 
可以看出,最后一种输出是真正想要的结果。
 
因此,要控制转义的问题,必须对XML重新格式化,格式化的时候,需要设置:
        xw.setEscapeText(false);

本文出自 “熔 岩 ” 博客,请务必保留此出处http://lavasoft.blog.51cto.com/62575/347348

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值