最近简单学习了分别使用DOM和DOM4J两种解析器生成XML文件的方法,下面我就这学习过程中遇到的问题简单说一下对这两种解析器的理解。
1.DOM
介绍:
DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。
实例:
import java.io.File;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class xmlDomTest{
public static void createXml(ArrayList<String[]> xmlObj,String filePath) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
// 设置xml是否可以单独存在
document.setXmlStandalone(true);
Element root = document.createElement("students"); //设置根节点
for (String[] obj : xmlObj){
Element student = document.createElement("student");
student.setAttribute("sex",obj[0]);
student.setAttribute("age",obj[1]); // 设置属性
Element name = document.createElement("name");
name.setTextContent(obj[2]); // 设置内容
student.appendChild(name);
root.appendChild(student);
}
document.appendChild(root);
DOMSource source = new DOMSource(document);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING,"utf-8"); // 编码
transformer.setOutputProperty(OutputKeys.INDENT,"yes"); // 缩进,默认为0
StreamResult result = new StreamResult(new File(filePath));
transformer.transform(source,result);
}
// 测试
public static void main(String[] args) throws Exception{
String[] student1 = {"女","19","张三"};
String[] student2 = {"男","20","李四"};
ArrayList<String[]> xmlObj = new ArrayList<String[]>();
xmlObj.add(student1);
xmlObj.add(student2);
String filePath = "D://test.xml";
createXml(xmlObj,filePath);
}
}
结果:
<?xml version="1.0" encoding="utf-8"?>
<students>
<student age="19" sex="女">
<name>张三</name>
</student>
<student age="20" sex="男">
<name>李四</name>
</student>
</students>
遇到的问题:
(1)从结果可以看出xml文件并没有缩进,很难看出各个节点之间的层次关系,如果想查看如何实现xml的缩进请查看DOM生成xml文件的时候如何控制xml的缩进格式。这篇博客很详细的说明了缩进的问题可能带来java版本不兼容的问题。
(2)属性出现的顺序与加入时的顺序不同,这其实并不是一个问题,对解析xml并没有影响,但是我们一般给节点加入属性时都会考虑到属性的主次关系,所以乱的属性的顺序很不方便用户查看。
后来别人给我推荐DOM4J去生成xml,发现DOM4J中并不存在这些问题。
2.DOM4J
介绍:
虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始,它就一直处于开发之中。
为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案,实现在本质上处理所有Java/XML问题的目标。在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为。DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J。
实例:
import java.io.FileWriter;
import java.io.File;
import java.util.ArrayList;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public class xmlDom4jTest {
public static void createXml(ArrayList<String[]> xmlObj,String filePath) throws Exception{
Document document = DocumentHelper.createDocument();
document.setXMLEncoding("UTF-8");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter pw = new XMLWriter(new FileWriter(new File(filePath)),format);
Element root = document.addElement("students"); //设置根节点
for (String[] obj : xmlObj){
Element student = root.addElement("student");
student.addAttribute("sex",obj[0]);
student.addAttribute("age",obj[1]); // 设置属性
Element name = student.addElement("name");
name.setText(obj[2]); // 设置内容
}
pw.write(document);
pw.close();
}
public static void main(String[] args) throws Exception{
String[] student1 = {"女",filePath);
}
}
结果:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student sex="女" age="19">
<name>张三</name>
</student>
<student sex="男" age="20">
<name>李四</name>
</student>
</students>