XML現在已經變成一個通用的資料交換格式,它的平台無關性,語言無關性,系統無關性,為資料整合與互動帶來了極大的方便。對於XML本身的語法知識與技術細節,需要閱讀相關的技術文獻,這裡麵包括的內容有DOM(Document Object Model),DTD(Document Type Definition),SAX(Simple API for XML),XSD(Xml Schema Definition ),XSLT(Extensible Stylesheet Language Transformations),具體可參閱w3c官方網站文件以取得更多資訊。
XML在不同的語言裡解析方式都是一樣的,只不過實現的語法不同而已。基本的解析方式有兩種,一種叫SAX#,另一種叫DOM。 SAX是基於事件流的解析,DOM是基於XML文檔樹結構的解析#。假設我們XML的內容與架構如下:
<?xml version="1.0" encoding="UTF-8"?><employees><employee> <name>ddviplinux</name> <sex>m</sex> <age>30</age></employee></employees>
本文使用JAVA語言來實作DOM與SAX的XML文件產生與解析。
先定義一個操作XML文件的介面XmlDocument 它定義了XML文件的建立與解析的介面。
package com.beyond.framework.bean; /** * @author zhengwei * 定义XML文档建立与解析的接口 */ public interface XmlDocument { /** * 建立XML文档 * @param fileName 文件全路径名称 */ public void createXml(String fileName); /** * 解析XML文档 * @param fileName 文件全路径名称 */ public void parserXml(String fileName); }
1. DOM產生與解析 XML文件
為XML 文件的已解析版本定義了一組介面。解析器讀入整個文檔,然後建立一個駐留記憶體的樹結構,然後程式碼就可以使用 DOM 介面來操作這個樹結構。
優點:整個文件樹在記憶體中,方便操作;支援刪除、修改、重新排列等多種功能;
缺點:將整個文件調入記憶體(包括無用的節點) ,浪費時間和空間;
使用場合:一旦解析了文件還需多次存取這些資料;硬體資源充足(記憶體、CPU)。
DomDemo ==.document = = .document.createElement("employees"= .document.createElement("employee"= .document.createElement("name".document.createTextNode("丁宏亮"= .document.createElement("sex".document.createTextNode("m"= .document.createElement("age".document.createTextNode("30"=== "gb2312""yes"= PrintWriter(= "生成XML文件成功!" ==== ( i = 0; i < employees.getLength(); i++== ( j = 0; j < employeeInfo.getLength(); j++== ( k = 0; k < employeeMeta.getLength(); k+++ ":" +"解析完毕"
2. SAX產生與解析 XML文件
為解決DOM的問題,出現了SAX。 SAX ,事件驅動。當解析器發現元素開始、元素結束、文字、文件的開始或結束等時,發送事件,程式設計師編寫回應這些事件的程式碼,保存資料。
優點:不用事先調入整個文檔,佔用資源少;SAX解析器程式碼比DOM解析器程式碼小,適於Applet,下載。
缺點:不是持久的;事件過後,若沒保存數據,那麼數據就丟了;無狀態性;從事件中只能得到文本,但不知該文本屬於哪個元素;
使用場合:Applet;只需XML文檔的少量內容,很少回頭訪問;機器內存少;
import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import javax.xml.parsers.ParserConfigurationException;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;/*** @author zhengwei * SAX文档解析*/public class SaxDemo implements XmlDocument { public void createXml(String fileName) { System.out.println("<<"+filename+">>"); } public void parserXml(String fileName) { SAXParserFactory saxfac = SAXParserFactory.newInstance(); try { SAXParser saxparser = saxfac.newSAXParser(); InputStream is = new FileInputStream(fileName); saxparser.parse(is, new MySAXHandler()); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } class MySAXHandler extends DefaultHandler { boolean hasAttribute = false; Attributes attributes = null; public void startDocument() throws SAXException { System.out.println("文档开始打印了"); } public void endDocument() throws SAXException { System.out.println("文档打印结束了"); } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equals("employees")) { return; } if (qName.equals("employee")) { System.out.println(qName); } if (attributes.getLength() > 0) { this.attributes = attributes; this.hasAttribute = true; } } public void endElement(String uri, String localName, String qName) throws SAXException { if (hasAttribute && (attributes != null)) { for (int i = 0; i < attributes.getLength(); i++) { System.out.println(attributes.getQName(0) + attributes.getValue(0)); } } } public void characters(char[] ch, int start, int length) throws SAXException { System.out.println(new String(ch, start, length)); } }
3. DOM4J產生與解析XML文件
DOM4J 是一個非常非常優秀的Java XML API,具有效能優異、功能強大且極端易用使用的特點,同時它也是一個開放原始碼的軟體。如今你可以看到越來越多的 Java 軟體都在使用 DOM4J 來讀寫 XML,特別值得一提的是連 Sun 的 JAXM 也在用 DOM4J。
import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.Iterator; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; /** * @author zhengwei * Dom4j 生成XML文档与解析XML文档 */ public class Dom4jDemo implements XmlDocument { public void createXml(String fileName) { Document document = DocumentHelper.createDocument(); Element employees=document.addElement("employees"); Element employee=employees.addElement("employee"); Element name= employee.addElement("name"); name.setText("ddvip"); Element sex=employee.addElement("sex"); sex.setText("m"); Element age=employee.addElement("age"); age.setText("29"); try { Writer fileWriter=new FileWriter(fileName); XMLWriter xmlWriter=new XMLWriter(fileWriter); xmlWriter.write(document); xmlWriter.close(); } catch (IOException e) { System.out.println(e.getMessage()); } } public void parserXml(String fileName) { File inputXml=new File(fileName); SAXReader saxReader = new SAXReader(); try { Document document = saxReader.read(inputXml); Element employees=document.getRootElement(); for(Iterator i = employees.elementIterator(); i.hasNext();){ Element employee = (Element) i.next();for(Iterator j = employee.elementIterator(); j.hasNext();){ Element node=(Element) j.next(); System.out.println(node.getName()+":"+node.getText()); } } } catch (DocumentException e) { System.out.println(e.getMessage()); } System.out.println("dom4j parserXml"); } }
4. JDOM#產生與解析XML
為減少DOM、SAX的編碼量,出現了JDOM;
優點:20-80原則,大幅減少了程式碼量。
使用場合:要實現的功能簡單,如解析、創建等,但在底層,JDOM還是使用SAX(最常用)、DOM、Xanan文件。
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter; /*** @author zhengwei * JDOM 生成与解析XML文档 */ public class JDomDemo implements XmlDocument { public void createXml(String fileName) { Document document; Element root; root=new Element("employees"); document=new Document(root); Element employee=new Element("employee"); root.addContent(employee); Element name=new Element("name"); name.setText("ddvip"); employee.addContent(name); Element sex=new Element("sex"); sex.setText("m"); employee.addContent(sex); Element age=new Element("age"); age.setText("23"); employee.addContent(age); XMLOutputter XMLOut = new XMLOutputter(); try { XMLOut.output(document, new FileOutputStream(fileName)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }public void parserXml(String fileName) { SAXBuilder builder=new SAXBuilder(false); try { Document document=builder.build(fileName); Element employees=document.getRootElement(); List employeeList=employees.getChildren("employee"); for(int i=0;i<EMPLOYEELIST.SIZE();I++){ iElement employee=(Element)employeeList.get(i); List employeeInfo=employee.getChildren(); for(int j=0;j<EMPLOYEEINFO.SIZE();J++){ System.out.println(((Element)employeeInfo.get(j)).getName()+":" +((Element)employeeInfo.get(j)).getValue()) } } } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
5.使用 dom4j 解析 XML
dom4j 是一種解析 XML 文件的開放原始碼 XML 框架。本文介紹如何使用包含在 dom4j 中的解析器建立並修改 XML 文件。
dom4j API 包含一個解析 XML 文件的工具。本文中將使用這個解析器建立一個範例 XML 文件。
清單1. 範例XML 文件(catalog.xml#)
<?xml version="1.0" encoding="UTF-8"?> <catalog> <!--An XML Catalog--> <?target instruction?><journal title="XML Zone" publisher="IBM developerWorks"> <article level="Intermediate" date="December-2001"> <title>Java configuration with XML Schema</title> <author> <firstname>Marcello</firstname> <lastname>Vitaletti</lastname> </author> </article></journal> </catalog>
接著使用同一個解析器修改catalog.xml,清單2 是修改後的XML 文檔,catalog-modified.xml。
清單2. 修改後的XML 文件(catalog-modified.xml)
<?xml version="1.0" encoding="UTF-8"?><catalog> <!--An XML catalog--><?target instruction?><journal title="XML Zone" publisher="IBM developerWorks"><article level="Introductory" date="October-2002"> <title>Create flexible and extensible XML schemas</title> <author><firstname>Ayesha</firstname> <lastname>Malik</lastname> </author> </article></journal></catalog>
與W3C DOM API 相比,使用dom4j 所包含的解析器的好處是dom4j 擁有本地的XPath 支援。 DOM 解析器不支援使用 XPath 選擇節點。
本文包含以下幾個部分:
預先設定
建立文件
#修改文件
預先設定
這個解析器可以從 取得。透過設定使 dom4j-1.4/dom4j-full.jar 能夠在 classpath 中訪問,該檔案中包括 dom4j 類別、XPath 引擎以及 SAX 和 DOM 介面。如果已經使用了 JAXP 解析器中包含的 SAX 和 DOM 接口,請向 classpath 增加 dom4j-1.4/dom4j.jar 。 dom4j.jar包含 dom4j 類別和 XPath 引擎,但不含 SAX 與 DOM 介面。
建立文件
本節討論使用 dom4j API 建立 XML 文件的流程,並建立範例 XML 文件 catalog.xml。
使用import 語句導入dom4j API 類別:
import org.dom4j.Document; #import org .dom4j.DocumentHelper; import org.dom4j.Element; |
# 使用DocumentHelper 類別建立一個文檔實例。 DocumentHelper 是產生 XML 文件節點的 dom4j API 工廠類別。
Document document = DocumentHelper.createDocument(); |
#
使用addElement() 方法建立根元素catalog 。 addElement() 用於在 XML 文件中增加元素。
Element catalogElement = document.addElement("catalog"); |
在catalog 元素中使用addComment() 方法新增註解「An XML catalog」。
catalogElement.addComment("An XML catalog"); |
在catalog 元素中使用addProcessingInstruction() 方法增加一個處理指令。
catalogElement.addProcessingInstruction("target","text"); |
在catalog 元素中使用addElement() 方法增加journal 元素。
Element journalElement = catalogElement.addElement("journal"); |
# #
使用addAttribute() 方法在journal 元素中加入title 和publisher 屬性。
journalElement.addAttribute("title", "XML Zone"); journalElement.addAttribute("publisher", " IBM developerWorks"); |
將journal 元素加入article 元素。
Element articleElement=journalElement.addElement("article"); |
為article 元素增加level 和date 屬性。
articleElement.addAttribute("level", "Intermediate"); articleElement.addAttribute("date", "December -2001"); |
# 將title 元素增加至article 元素。
Element titleElement=articleElement.addElement("title"); |
使用setText() 方法來設定article 元素的文字。
titleElement.setText("Java configuration with XML Schema"); |
在article 元素中增加author 元素。
Element authorElement=articleElement.addElement("author"); |
在author 元素中增加firstname 元素並設定該元素的文字。
Element firstNameElement=authorElement.addElement("firstname"); firstNameElement.setText("Marcello"); |
在author 元素中增加lastname 元素並設定此元素的文字。
Element lastNameElement=authorElement.addElement("lastname"); lastNameElement.setText("Vitaletti"); |
可以使用 addDocType()方法添加文档类型说明。
document.addDocType("catalog", null,"file://c:/Dtds/catalog.dtd"); |
这样就向 XML 文档中增加文档类型说明:
如果文档要使用文档类型定义(DTD)文档验证则必须有 Doctype。
XML 声明 自动添加到 XML 文档中。
清单 3 所示的例子程序 XmlDom4J.java 用于创建 XML 文档 catalog.xml。
清单 3. 生成 XML 文档 catalog.xml 的程序(XmlDom4J.java)
import org.dom4j.Document;import org.dom4j.DocumentHelper;import org.dom4j.Element;import org.dom4j.io.XMLWriter;import java.io.*;public class XmlDom4J{public void generateDocument(){ Document document = DocumentHelper.createDocument(); Element catalogElement = document.addElement("catalog"); catalogElement.addComment("An XML Catalog"); catalogElement.addProcessingInstruction("target","text"); Element journalElement = catalogElement.addElement("journal"); journalElement.addAttribute("title", "XML Zone"); journalElement.addAttribute("publisher", "IBM developerWorks"); Element articleElement=journalElement.addElement("article"); articleElement.addAttribute("level", "Intermediate"); articleElement.addAttribute("date", "December-2001"); Element titleElement=articleElement.addElement("title"); titleElement.setText("Java configuration with XML Schema"); Element authorElement=articleElement.addElement("author"); Element firstNameElement=authorElement.addElement("firstname"); firstNameElement.setText("Marcello"); Element lastNameElement=authorElement.addElement("lastname"); lastNameElement.setText("Vitaletti"); document.addDocType("catalog",null,"file://c:/Dtds/catalog.dtd");try{ XMLWriter output = new XMLWriter( new FileWriter(new File("c:/catalog/catalog.xml"))); output.write( document ); output.close(); } catch(IOException e){ System.out.println(e.getMessage()); } }public static void main(String[] argv){ XmlDom4J dom4j=new XmlDom4J(); dom4j.generateDocument(); } }
这一节讨论了创建 XML 文档的过程,下一节将介绍使用 dom4j API 修改这里创建的 XML 文档。
修改文档
这一节说明如何使用 dom4j API 修改示例 XML 文档 catalog.xml。
使用 SAXReader 解析 XML 文档 catalog.xml:
SAXReader saxReader = new SAXReader(); Document document = saxReader.read(inputXml);
SAXReader 包含在 org.dom4j.io 包中。
inputXml 是从 c:/catalog/catalog.xml 创建的 java.io.File。使用 XPath 表达式从 article 元素中获得 level 节点列表。如果 level 属性值是“Intermediate”则改为“Introductory”。
List list = document.selectNodes("//article/@level" ); Iterator iter=list.iterator(); while(iter.hasNext()){ Attribute attribute=(Attribute)iter.next(); if(attribute.getValue().equals("Intermediate")) attribute.setValue("Introductory"); }
获取 article 元素列表,从 article 元素中的 title 元素得到一个迭代器,并修改 title 元素的文本。
list = document.selectNodes("//article" ); iter=list.iterator(); while(iter.hasNext()){ Element element=(Element)iter.next(); Iterator iterator=element.elementIterator("title"); while(iterator.hasNext()){ Element titleElement=(Element)iterator.next(); if(titleElement.getText().equals("Java configuration with XML Schema")) titleElement.setText("Create flexible and extensible XML schema"); } }
通过和 title 元素类似的过程修改 author 元素。
清单 4 所示的示例程序 Dom4JParser.java 用于把 catalog.xml 文档修改成 catalog-modified.xml 文档。
清单 4. 用于修改 catalog.xml 的程序(Dom4Jparser.java)
import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.Attribute;import java.util.List;import java.util.Iterator;import org.dom4j.io.XMLWriter;import java.io.*;import org.dom4j.DocumentException;import org.dom4j.io.SAXReader;public class Dom4JParser{public void modifyDocument(File inputXml){try{ SAXReader saxReader = new SAXReader(); Document document = saxReader.read(inputXml); List list = document.selectNodes("//article/@level" ); Iterator iter=list.iterator();while(iter.hasNext()){ Attribute attribute=(Attribute)iter.next();if(attribute.getValue().equals("Intermediate")) attribute.setValue("Introductory"); } list = document.selectNodes("//article/@date" ); iter=list.iterator();while(iter.hasNext()){ Attribute attribute=(Attribute)iter.next();if(attribute.getValue().equals("December-2001")) attribute.setValue("October-2002"); } list = document.selectNodes("//article" ); iter=list.iterator();while(iter.hasNext()){ Element element=(Element)iter.next(); Iterator iterator=element.elementIterator("title");while(iterator.hasNext()){ Element titleElement=(Element)iterator.next();if(titleElement.getText().equals("Java configuration with XMLSchema")) titleElement.setText("Create flexible and extensible XML schema"); } } list = document.selectNodes("//article/author" ); iter=list.iterator();while(iter.hasNext()){ Element element=(Element)iter.next(); Iterator iterator=element.elementIterator("firstname");while(iterator.hasNext()){ Element firstNameElement=(Element)iterator.next();if(firstNameElement.getText().equals("Marcello")) firstNameElement.setText("Ayesha"); } } list = document.selectNodes("//article/author" ); iter=list.iterator();while(iter.hasNext()){ Element element=(Element)iter.next(); Iterator iterator=element.elementIterator("lastname");while(iterator.hasNext()){ Element lastNameElement=(Element)iterator.next();if(lastNameElement.getText().equals("Vitaletti")) lastNameElement.setText("Malik"); } } XMLWriter output = new XMLWriter(new FileWriter( new File("c:/catalog/catalog-modified.xml") )); output.write( document ); output.close(); } catch(DocumentException e) { System.out.println(e.getMessage()); } catch(IOException e){ System.out.println(e.getMessage()); } }public static void main(String[] argv){ Dom4JParser dom4jParser=new Dom4JParser(); dom4jParser.modifyDocument(new File("c:/catalog/catalog.xml")); } }
结束语:包含在 dom4j 中的解析器是一种用于解析 XML 文档的非验证性工具,可以与JAXP、Crimson 或 Xerces 集成。本文说明了如何使用该解析器创建和修改 XML 文档。
以上是解析XML的四種方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!