解析XML文件(二)----使用dom4j方式(三)

前端之家收集整理的这篇文章主要介绍了解析XML文件(二)----使用dom4j方式(三)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

dom4j和jdom都是非常优秀的xml解析工具,但现在很多人认为dom4j无论是在性能上或是灵活性上都要优于jdom,其实,作为xml的解析工具,他们在大多情况下都能满足我们的要求。至于要选择使用哪一个,那就要依个人爱好(或是公司要求)了。

以前写了一个jdom解析xml 的例子,仿照那篇,再写一个dom4j版本的。

我下载的是dom4j-1.6.1.zip,解压后可以看到里面有个dom4j-1.6.1.jar,为了方便,要使用了XPath的寻址方式时,需要引入jaxen-1.1-beta-6.jar(在lib文件夹中)。引入了这两个包,就可以开始操作xml文件了。dom4j的包11M多,超过限制了,此处只把例子中用到的两个jar包传上来。

dom4j-1.6.1.zip的下载地址为http://sourceforge.net/projects/dom4j/

下面分别对应读、写、修改写了三个例子。

一、读取xml文件

假设有这样一个xml文件

  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <sys-config>
  3. <jdbc-info>
  4. <driver-class-name>oracle.jdbc.driver.OracleDriver</driver-class-name>
  5. <url>jdbc:oracle:thin:@localhost:1521:database</url>
  6. <user-name>why</user-name>
  7. <password>why</password>
  8. </jdbc-info>
  9. <provinces-info>
  10. <provinceid="hlj"name="黑龙江">
  11. <cityid="harb">哈尔滨</city>
  12. <cityid="nj">嫩江</city>
  13. </province>
  14. <provinceid="jl"name="吉林"></province>
  15. </provinces-info>
  16. </sys-config>

首先,我们需要获得要解析的xml文件。dom4j提供DOMReader和SAXReader两种不同方式获取xml文件,但他们的调用方式是一样的。reader的read方法是重载的,可以从InputStream,File,Url等多种不同的源来读取,会返回一个org.dom4j.Document对象,得到的Document对象就带表了整个XML。

然后,可以用document.getRootElement()方法获取根节点,并从根节点开始遍历xml文档。当然,我们也可以越过此步骤,而使用XPath直接获得要操作的节点(这与jdom有一点区别,jdom需要先获得根节点才可以使用XPath方式进行遍历)。利用 document.selectNodes("nodeName") 可以取得xml中的任意制定的节点中的信息。如:

Element driverClassNameElement = (Element)document.selectSingleNode("//sys-config/jdbc-info/driver-class-name");

这样就取得了上面文件中的 <jdbc-info> 下的 <driver-class-name> 中的内容

如果一个节点下有多个名称相同的子节点,可以用document.selectNodes()方法取得多个子节点的List,遍历这个List就可以操作各个子节点的内容了。org.dom4j.Element对象代表每个节点。

下面是我写的用dom4j读取上面xml文件的例子:

Java代码
  1. packagecom.why.dom4j;
  2. importjava.io.File;
  3. importjava.util.Iterator;
  4. importjava.util.List;
  5. importorg.dom4j.Document;
  6. importorg.dom4j.DocumentException;
  7. importorg.dom4j.Element;
  8. importorg.dom4j.io.SAXReader;
  9. publicclassReadXml{
  10. /**
  11. *@paramargs
  12. */
  13. publicstaticvoidmain(String[]args){
  14. SAXReadersaxReader=newSAXReader();
  15. try{
  16. Documentdocument=saxReader.read(newFile("src/config.xml"));
  17. //ElementrootEle=document.getRootElement();//获取根节点
  18. ElementdriverClassNameElement=(Element)document.selectSingleNode("//sys-config/jdbc-info/driver-class-name");
  19. StringdriverClassName=driverClassNameElement.getText();
  20. System.out.println("driverClassName="+driverClassName);
  21. ListprovinceList=document.selectNodes("//sys-config/provinces-info/province");
  22. for(Iteratorit=provinceList.iterator();it.hasNext();){
  23. ElementprovinceEle=(Element)it.next();
  24. StringproId=provinceEle.attributeValue("id");
  25. StringproName=provinceEle.attributeValue("name");
  26. System.out.println("provinceId="+proId+"provinceName="+proName);
  27. ListcityEleList=(List)provinceEle.elements("city");
  28. for(IteratorcityIt=cityEleList.iterator();cityIt.hasNext();){
  29. ElementcityEle=(Element)cityIt.next();
  30. StringcityId=cityEle.attributeValue("id");
  31. StringcityName=cityEle.getText();
  32. System.out.println("cityId="+cityId+"cityName="+cityName);
  33. }
  34. }
  35. }catch(DocumentExceptione){
  36. e.printStackTrace();
  37. }
  38. }
  39. }

二、写xml文件

首先,用DocumentHelper.createDocument()方法创建一个Document对象,并调用document.addElement()来创建一个根节点。

然后,用Element的addElement()为一个节点添加子节点,addAttribute()方法添加属性

构造完xml文档结构后,使用org.dom4j.io.XMLWriter的write()方法,将构造好的文档输出到指定位置,当然,可以用org.dom4j.io.OutputFormat对生成的文档进行美化。

代码如下:

Java代码
  1. packagecom.why.dom4j;
  2. importjava.io.FileWriter;
  3. importjava.io.IOException;
  4. importorg.dom4j.Document;
  5. importorg.dom4j.DocumentHelper;
  6. importorg.dom4j.Element;
  7. importorg.dom4j.io.OutputFormat;
  8. importorg.dom4j.io.XMLWriter;
  9. publicclassWriteXML{
  10. /**
  11. *@paramargs
  12. */
  13. publicstaticvoidmain(String[]args){
  14. Documentdocument=DocumentHelper.createDocument();
  15. Elementroot=document.addElement("sys-config");
  16. ElementprovinceEle=
  17. root.addElement("provinces-info")
  18. .addElement("province")
  19. .addAttribute("id","hlj")
  20. .addAttribute("name","黑龙江省");
  21. ElementcityEle1=provinceEle.addElement("city");
  22. cityEle1.addAttribute("id","harb");
  23. cityEle1.addText("哈尔滨");
  24. ElementcityEle2=
  25. provinceEle.addElement("city")
  26. .addAttribute("id","nj")
  27. .addText("嫩江");
  28. //OutputFormatformat=OutputFormat.createPrettyPrint();//美化格式
  29. OutputFormatformat=OutputFormat.createCompactFormat();//缩减格式
  30. //format.setEncoding("UTF-8");//设置编码格式
  31. format.setIndent("");//缩进4个空格后换行
  32. XMLWriterwriter;
  33. try{
  34. writer=newXMLWriter(newFileWriter("src/output.xml"),format);
  35. writer.write(document);
  36. writer.close();
  37. }catch(IOExceptione){
  38. e.printStackTrace();
  39. }
  40. StringxmlStr=document.asXML();
  41. System.out.println(xmlStr);
  42. //也可以将字符串转XML
  43. //Stringtext="<sys-config><provinces-info><province>黑龙江省</province></provinces-info></sys-config>";
  44. //Documentdocument=DocumentHelper.parseText(text);
  45. }
  46. }

三、修改xml文件

以上面的xml为例,现进行三项修改

1、在<province id="jl" name="吉林"></province>之间添加一个子节点<city id="jls">吉林市</city>:

首先取得id="jl"的province节点,然后调用addElement()方法添加子节点,与写文件操作相同,如:

province.addElement("city").addAttribute("id","jls").addText("吉林市");

2、将<city id="harb">哈尔滨</city>的id属性改为“HaErBin”,内容改为“哈尔滨市”:

遍历所有的city节点,并取得其“id”属性:Attribute attribute = (Attribute)city.attribute("id");

若其“id”属性的值为“harb”,则调用其attribute属性的setValue()方法:attribute.setValue("HaErBin");并调用该city节点的setText()方法将其内容改为“哈尔滨市”。

3、删除<city id="nj">嫩江</city>节点:

取得id="nj"的city节点,并调用其父节点的remove()方法删除此节点:city.getParent().remove(city);

代码如下:

Java代码
  1. packagecom.why.dom4j;
  2. importjava.io.File;
  3. importjava.io.FileOutputStream;
  4. importjava.io.IOException;
  5. importjava.util.Iterator;
  6. importjava.util.List;
  7. importorg.dom4j.Attribute;
  8. importorg.dom4j.Document;
  9. importorg.dom4j.DocumentException;
  10. importorg.dom4j.Element;
  11. importorg.dom4j.io.OutputFormat;
  12. importorg.dom4j.io.SAXReader;
  13. importorg.dom4j.io.XMLWriter;
  14. publicclassModifyXml{
  15. /**
  16. *@paramargs
  17. */
  18. publicstaticvoidmain(String[]args){
  19. SAXReadersaxReader=newSAXReader();
  20. Filefile=newFile("src/config.xml");
  21. try{
  22. Documentdocument=saxReader.read(file);
  23. ListprovinceList=(List)document.selectNodes("//sys-config/provinces-info/province");
  24. for(Iteratorit=provinceList.iterator();it.hasNext();){
  25. Elementprovince=(Element)it.next();
  26. Attributeattribute=(Attribute)province.attribute("id");
  27. System.out.println(attribute.getValue());
  28. if(attribute.getValue().equals("jl")){
  29. System.out.println(province.getText());
  30. province.addElement("city")
  31. .addAttribute("id","jls").addText("吉林市");
  32. }
  33. }
  34. ListcityList=(List)document.selectNodes("//sys-config/provinces-info/province/city");
  35. for(Iteratorit=cityList.iterator();it.hasNext();){
  36. Elementcity=(Element)it.next();
  37. Attributeattribute=(Attribute)city.attribute("id");
  38. System.out.println(attribute.getValue());
  39. if(attribute.getValue().equals("harb")){
  40. attribute.setValue("HaErBin");
  41. System.out.println(city.getText());
  42. city.setText("哈尔滨市");
  43. }
  44. if(attribute.getValue().equals("nj")){
  45. city.getParent().remove(city);
  46. }
  47. }
  48. OutputFormatformat=OutputFormat.createPrettyPrint();
  49. format.setEncoding("UTF-8");//设置编码格式
  50. format.setIndent("");//缩进4个空格后换行
  51. XMLWriterwriter=newXMLWriter(newFileOutputStream(file),format);
  52. writer.write(document);
  53. writer.close();
  54. }catch(DocumentExceptione){
  55. e.printStackTrace();
  56. }catch(IOExceptione){
  57. e.printStackTrace();
  58. }
  59. }
  60. }

Invalid byte 1 of 1-byte UTF-8 sequence的解决办法:

将new XMLWriter(new FileWriter("src/output.xml"),format);改为:

new XMLWriter(new FileOutputStream("src/output.xml"),format);

为避免程序中出现中文乱码问题,也可以将xml文件以及程序中设置的编码格式统一改为GBK,有关中文乱码的问题,可以参考http://kevin-qingzhan.iteye.com/blog/473994

猜你在找的XML相关文章