java解析xml分爲兩類,4種,分別爲SAX解析,dom解析,jdom,dom4j.以下具體舉例使用4種方式來實現對一個.xml文件進行解析:
有命名爲dome.xml的文件,
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="1">
<name>java教程</name>
<price>89</price>
<language>英文</language>
<year>2005</year>
</book>
<book id="2">
<name>php教程</name>
<price>65</price>
<language>中文</language>
<year>2011</year>
</book>
<book id="3">
<name>c語言</name>
<price>33</price>
<language>中文</language>
<year>2015</year>
</book>
</books>
1.使用dom4j的方式來實現對dome.xml文件的解析:
DOM4J 是一個非常非常優秀的Java XML API,具有性能優異、功能強大和極端易用使用的特點,同時它也是一個開放源代碼的軟件。如今你可以看到越來越多的 Java 軟件都在使用 DOM4J 來讀寫 XML,特別值得一提的是連 Sun 的 JAXM 也在用 DOM4J。
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class dom4j_xml {
public static void main(String[] args) {
// TODO Auto-generated method stub
dom4j_xml a=new dom4j_xml();
a.DOM4J_xml();
}
public void DOM4J_xml() {
int book_index=0;
try {
SAXReader reader=new SAXReader();//創建解析對象
Document document=reader.read(new File("demo.xml"));//加載xml文檔
Element book_root=document.getRootElement();//得到加載xml文檔的根標籤
Iterator iterator=book_root.elementIterator();//加載跟標籤以下的所有標籤,返回值是一個迭代器對象
while(iterator.hasNext()){//開始遍歷,調用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());//得到屬性名和對應的屬性值,即key-value
}
Iterator book_node_iter=book.elementIterator();//獲取根節點以下的子子節點,
while(book_node_iter.hasNext()){//遍歷所有的子子節點
Element book_node=(Element)book_node_iter.next();//獲取子子節點 Element
System.out.println(book_node.getName()+":"+book_node.getStringValue());
}//獲取標籤名和標籤中的Text值
System.out.println("============第"+(book_index)+"本結束==========");
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
輸出結果如下:
2.使用dom解析xml文件的方式:
爲 XML 文檔的已解析版本定義了一組接口。解析器讀入整個文檔,然後構建一個駐留內存的樹結構,然後代碼就可以使用 DOM 接口來操作這個樹結構。優點:整個文檔樹在內存中,便於操作;支持刪除、修改、重新排列等多種功能;缺點:將整個文檔調入內存(包括無用的節點),浪費時間和空間;使用場合:一旦解析了文檔還需多次訪問這些數據;硬件資源充足(內存、CPU)。
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.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();
}
public void xml_dom_parse() {
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db=dbf.newDocumentBuilder();
Document docu=db.parse("demo.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();
}
}
}
輸出結果如下:
3.使用jdom解析xml文件:
爲減少DOM、SAX的編碼量,出現了JDOM;優點:20-80原則,極大減少了代碼量。使用場合:要實現的功能簡單,如解析、創建等,但在底層,JDOM還是使用SAX(最常用)、DOM、Xanan文檔。
import java.awt.print.Book;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.jdom.Attribute;
import org.jdom.CDATA;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
public class jdom_xml {
public static List<Books> books_list=new ArrayList<Books>();
public static void main(String[] args) {
new jdom_xml().JDOM();
}
public void JDOM() {
SAXBuilder builder=new SAXBuilder();
try {
Document document=builder.build(new FileInputStream("demo.xml"));
Element book_root=document.getRootElement();
//獲去所有的書籍
List<Element> book_list=book_root.getChildren();
for (Element book : book_list) {
System.out.println("==========第"+(book_list.indexOf(book)+1)+"本書===========");
Books books=new Books();
List<Attribute> book_attr=book.getAttributes();
for (Attribute attr : book_attr) {
System.out.println(attr.getName()+":"+attr.getValue());
if(attr.getName().equals("id")){
books.setId(attr.getValue());
}
}
List<Element> book_children=book.getChildren();
for (Element element : book_children) {
System.out.println(element.getName()+":"+element.getValue());
if(element.getName().equals("year")){
books.setYear(element.getValue());
}else if(element.getName().equals("name")){
books.setName(element.getValue());
}else if(element.getName().equals("price")){
books.setPrice(element.getValue());
}else if(element.getName().equals("language")){
books.setLanguage(element.getValue());
}
}
books_list.add(books);
books=null;
System.out.println(books_list.size());
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
運行結果如下:
4.使用SAX解析xml文件:
爲解決DOM的問題,出現了SAX。SAX ,事件驅動。當解析器發現元素開始、元素結束、文本、文檔的開始或結束等時,發送事件,程序員編寫響應這些事件的代碼,保存數據。優點:不用事先調入整個文檔,佔用資源少;SAX解析器代碼比DOM解析器代碼小,適於Applet,下載。缺點:不是持久的;事件過後,若沒保存數據,那麼數據就丟了;無狀態性;從事件中只能得到文本,但不知該文本屬於哪個元素;使用場合:Applet;只需XML文檔的少量內容,很少回頭訪問;機器內存少;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXHandle extends DefaultHandler {
private int book_index=0;
public Books book;
String value;
ArrayList<Books> book_list=new ArrayList<Books>();
//標籤開始時調用
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
if(qName.equals("book")){
book=new Books();
book_index++;
for(int i=0;i<attributes.getLength();i++){
//System.out.println(attributes.getQName(i)+":"+attributes.getValue(i));
if(attributes.getQName(i).equals("id")){
book.setId(attributes.getValue("id"));
}
}
}
}
//標籤結束時調用
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
if(qName.equals("book")){
book_list.add(book);
book=null;
//System.out.println("---------"+(book_index)+"------結束------");
}else if (qName.equals("name")) {
book.setName(value);
}else if (qName.equals("language")) {
book.setLanguage(value);
}else if (qName.equals("year")) {
book.setYear(value);
}else if (qName.equals("price")) {
book.setPrice(value);
}
}
//讀取標籤內嵌內容
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
value=new String(ch, start, length);
//if(!value.trim().equals(""))
//System.out.println(value);
}
}
在新建一個類SAX_xml生成SAXHandle的實例化對象
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.swing.TransferHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
public class SAX_xml {
public void sax_xml(SAXHandle handler) {
SAXParserFactory factory= SAXParserFactory.newInstance();
try {
SAXParser parser=factory.newSAXParser();
parser.parse("demo.xml", handler);
List<Books> l = handler.book_list;
for (Books o : l) {
System.out.println(o);
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SAX_xml sax=new SAX_xml();
SAXHandle handler=new SAXHandle();
sax.sax_xml(handler);
}
}
運行結果如下:
以上4種解析的實例各有優缺;