首言
java中解析xml文件有四种方式,分别是DOM、SAX、JDOM、DOM4J,这四种前两种是系统自带的,后两种需要导入jar包,其中先要对xml文件有一个基本的了解。xml文件是为了不同程序,不同平台之间数据传输,不同数据平台的数据共享的作用。是以树形结构的存储的。XML 被设计用来传输和存储数据,其焦点是数据的内容。DOM解析
1)DOM(JAXP Crimson解析器)
DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。
节点类型 | named constant | nodeName()的返回值 | nodeValue()的返回值 |
name | ELEMENT_NODE | element name | null |
Attr | ATTRIBUTE_NODE | 属性名称 | 属性值 |
text | TEXT_NODE | #text | 节点内容 |
package project_xml;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
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;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class xml_dom {
public static void main(String[] args) {
xml_dom xml_dom1=new xml_dom();
xml_dom1.xml_dom_parse();
//xml_dom1.creat_xml();
}
public void xml_dom_parse() {
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db=dbf.newDocumentBuilder();
Document docu=db.parse("book.xml");
//获取所有的书籍节点
NodeList booklist=docu.getElementsByTagName("book");
for(int i =0;i<booklist.getLength();i++){
Node book_item=booklist.item(i);
System.out.println("第"+(i+1)+"本书");
NamedNodeMap node_att=book_item.getAttributes();//读取属性,并存在一个<span style="font-family: Arial, Helvetica, sans-serif;">NamedNodeMap中</span>
for(int j=0;j<node_att.getLength();j++){
Node node=node_att.item(j);
System.out.print(node.getNodeName()+":"+node.getNodeValue()+" ");
System.out.println();
}
NodeList book_child=book_item.getChildNodes();
for(int k=0;k<book_child.getLength();k++){
Node book_child_ele=book_child.item(k);
if(book_child_ele.getNodeType()==Node.ELEMENT_NODE){//如果没有会打印出很多空格,因为text也是一种节点类型,
//System.out.println(book_child_ele.getNodeName()+":"+book_child_ele.getFirstChild().getNodeValue());
这个就是采集到这个<name></name>中所有的所有的text
System.out.println(book_child_ele.getNodeName()+":"+book_child_ele.getTextContent());
}
}
System.out.println("以上就是第"+(i+1)+"本书");
}
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void creat_xml() {
try {
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db=dbf.newDocumentBuilder();
Document document=db.newDocument();
//可以将standalone设置为true,这样就不会显示了,表示的意思是不需要说明文档
document.setXmlStandalone(true);
Element bookstore=document.createElement("bookstore");
Element book=document.createElement("book");
Element name=document.createElement("name");
name.setTextContent("安徒生童话");
book.setAttribute("id", "1");
book.setAttribute("size", "lower");
book.appendChild(name);
bookstore.appendChild(book);
document.appendChild(bookstore);
TransformerFactory tf=TransformerFactory.newInstance();
Transformer transformer=tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(new DOMSource(document), new StreamResult(new File("book1.xml")));
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book id="1" size="medium">
<name >安徒生童话</name>
<price>89</price>
<language>英文</language>
<year>2004</year>
</book>
<book id="2" size="lower">
<name>一千零一夜</name>
<price>65</price>
<language>日语</language>
<year>2014</year>
</book>
<book id="3" size="large">
<name>美好</name>
<price>99</price>
<language>中文</language>
<year>2015</year>
</book>
</bookstore>
2)DOM4J http://dom4j.sourceforge.net/
虽然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。
public class dom4j_xml {
public static void main(String[] args) {
// TODO Auto-generated method stub
dom4j_xml a=new dom4j_xml();
a.creat_dom4j();
}
public void DOM4J_xml() {
int book_index=0;
try {
SAXReader reader=new SAXReader();
Document document=reader.read(new File("book.xml"));
Element book_root=document.getRootElement();
Iterator iterator=book_root.elementIterator();
while(iterator.hasNext()){
book_index++;
Element book=(Element)iterator.next();
List<Attribute> book_attr=book.attributes();
for (Attribute attribute : book_attr) {
System.out.println(attribute.getName()+":"+attribute.getValue());
}
Iterator book_node_iter=book.elementIterator();
while(book_node_iter.hasNext()){
Element book_node=(Element)book_node_iter.next();
System.out.println(book_node.getName()+":"+book_node.getStringValue());
}
System.out.println("============第"+(book_index)+"本结束==========");
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void creat_dom4j() {
Document document=DocumentHelper.createDocument();
Element element_rss=document.addElement("rss");
element_rss.addAttribute("version", "2.0");
Element element_channel=element_rss.addElement("channel");
Element element_title=element_channel.addElement("title");
element_title.setText("我们是爱好啥打法和");
OutputFormat format=OutputFormat.createPrettyPrint();
//format.setEncoding("");
try {
XMLWriter writer=new XMLWriter(new FileOutputStream(new File("rss.xml")), format);
//write中的方法,可以设置是否转义字符
writer.setEscapeText(false);
writer.write(document);
writer.close();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
创建SAXReader的对象reader,用过reader对象的read方法加载book,xml文件,并获取document对象
通过document对象获取根节点的bookstores,通过element对象的elementIterator方法获取迭代器
遍历迭代器,获取根节点中的信息,获取节点时可以通过迭代器再迭代下就可以了
比较
1)DOM4J性能最好,连Sun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J.
2)JDOM和DOM在性能测试时表现不佳,在测试10M文档时内存溢出。在小文档情况下还值得考虑使用DOM和JDOM。虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。另外,DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础,因为它正式获得W3C推荐(与基于非标准的Java模型相对),所以在某些类型的项目中可能也需要它(如在JavaScript中使用DOM)。
3)SAX表现较好,这要依赖于它特定的解析方式-事件驱动。一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。