XML解析
DOM(Document Object Model)解析
優點:增刪改查方便
缺點:需要讀取整個xml才能構建DOM樹。對於較大的xml,容易內存溢出
SAX(Simple API for XML)解析
優點:在讀取文檔的時候,即對文檔進行處理,而不必等到整個文檔裝載完纔會文檔進行操作
缺點:不是持久的;事件過後,若沒保存數據,那麼數據就丟了;無狀態性;從事件中只能得到文本,但不知該文本屬於哪個元素
適用於只查詢
JAXP(Java API for XML Processing)
可以進行DOM解析和SAX解析,由SUN公司提供,存在於JDK中
所在包:
org.w3c.dom:提供DOM方式解析XML的標準接口
org.xml.sax:提供SAX方式解析XML的標準接口
javax.xml:提供瞭解析XML文檔的類
JAXP調用dom方式創建xml
創建一個如下所示的xml文件
<?xml version="1.0" encoding="UTF-8"?> <recipe type="dessert"> <recipename cuisine="american" servings="1">Ice Cream Sundae</recipename> </recipe>
java代碼如下:
public static void createXML(String fileName) throws Exception{ //獲取DocumentBuilderFactory DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //獲取DocumentBuilder DocumentBuilder builder = factory.newDocumentBuilder(); //獲取Document對象 Document document = builder.newDocument(); //設置xml聲明 document.setXmlStandalone(false);//指定此文檔是否是單獨的的屬性 //創建跟元素 <recipe type="dessert"> Element rootElement = document.createElement("recipe"); //設置元素屬性 rootElement.setAttribute("type", "dessert"); //創建元素<recipename> Element recipename = document.createElement("recipename"); //爲recipename元素添加屬性 recipename.setAttribute("cuisine", "american"); recipename.setAttribute("servings", "1"); //設置recipename元素中的值 recipename.setTextContent("Ice Cream Sundae"); rootElement.appendChild(recipename); //將根元素添加到document中 document.appendChild(rootElement); //將xml映射到文件 boolean flag = true; try{ //獲取TransformerFactorty 用於創建 Transformer 和 Templates 對象。 TransformerFactory tf = TransformerFactory.newInstance(); //獲取Transformer對象 處理來自不同源的 XML,並將轉換輸出寫入各種接收器 //注意:在多線程同時運行時不能使用此類的對象 Transformer transformer = tf.newTransformer(); DOMSource source = new DOMSource(document); //設置編碼格式 transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //設置indent = "yes" | "no". indent 指定了當輸出結果樹時,Transformer 是否可以添加額外的空白;其值必須爲 yes 或 no。就是幽默誒有進行格式化 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); PrintWriter pw = new PrintWriter(new FileOutputStream(fileName)); StreamResult result = new StreamResult(pw); transformer.transform(source, result); }catch(Exception e){ flag = false; e.printStackTrace(); } if(flag){ System.out.println("生成XML文件成功!"); }else{ System.out.println("生成XML文件失敗!"); } }
JAXP調用SAX解析XML
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { //創建解析器工廠, SAXParserFactory spf = SAXParserFactory.newInstance(); //得到解析器, SAXParser parser = spf.newSAXParser(); //得到讀取器 XMLReader reader = parser.getXMLReader(); //給內容註冊內容處理器 // reader.setContentHandler(new MyContentHandler()); reader.setContentHandler(new DefaultHandler(){ public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); System.out.println("讀取文檔開始"); } public void endDocument() throws SAXException { // TODO Auto-generated method stub super.endDocument(); System.out.println("讀取文檔結束"); } }); //解析文檔 reader.parse("book.xml"); }
由於dom用來增刪改比較方便,所以選擇了用期進行創建修改操作,而SAX方式可以快速的進行查找便利,所以選擇用來做解析遍歷,此處就不在編寫dom解析xml的方式了。
第三方解析XML--DOM4J
解析XML,對XML進行遍歷
首先要獲取到一個Document對象
public Document parse(URL url) throws DocumentException { SAXReader reader = new SAXReader(); Document document = reader.read(url); return document; }
然後開始進行遍歷,在文檔中找到兩種方法見代碼:
//方法1 public void bar(Document document) throws DocumentException { Element root = document.getRootElement(); // iterate through child elements of root for ( Iterator i = root.elementIterator(); i.hasNext(); ) { Element element = (Element) i.next(); // do something } // iterate through child elements of root with element name "foo" for ( Iterator i = root.elementIterator( "foo" ); i.hasNext(); ) { Element foo = (Element) i.next(); // do something } // iterate through attributes of root for ( Iterator i = root.attributeIterator(); i.hasNext(); ) { Attribute attribute = (Attribute) i.next(); // do something } } //方法2 public void treeWalk(Document document) { treeWalk( document.getRootElement() ); } public void treeWalk(Element element) { for ( int i = 0, size = element.nodeCount(); i < size; i++ ) { Node node = element.node(i); if ( node instanceof Element ) { treeWalk( (Element) node ); } else { // do something.... } } }
在文檔中表明:如果說xml文件比較大的話,建議用第二種方法,可以避免了創建每個循環迭代器對象的成本。
Dom4j創建xml
/** *創建XML */ public Document createDocument() { Document document = DocumentHelper.createDocument(); Element root = document.addElement( "root" ); Element author1 = root.addElement( "author" ) .addAttribute( "name", "James" ) .addAttribute( "location", "UK" ) .addText( "James Strachan" ); Element author2 = root.addElement( "author" ) .addAttribute( "name", "Bob" ) .addAttribute( "location", "US" ) .addText( "Bob McWhirter" ); return document; } /** *將XML進行持久化(保存到文件) */ public void write(Document document) throws IOException { XMLWriter writer = new XMLWriter( new FileWriter( "output.xml" ) ); writer.write( document ); writer.close(); /*這個地方是定義輸出格式 *OutputFormat.createPrettyPrint() 方便閱讀的格式(帶空格,帶換行) *OutputFormat.createCompactFormat();沒有空格換行 *format.setEncoding(String encoding) 可以設置編碼格式,默認utf-8 */ OutputFormat format = OutputFormat.createPrettyPrint(); writer = new XMLWriter( System.out, format ); writer.write( document ); }
以上dom4j代碼摘自文檔中