Dom4j 學(xué)習(xí)筆記
The dom4j Project Homepage: http://www.dom4j.org
Loading XML Data
以下代碼從File中或一個(gè)URL中讀取一個(gè)XML文件,并產(chǎn)生一個(gè)Document對象。一個(gè)Document對象表示了內(nèi)存中的一棵XML樹,可以在這個(gè)XML樹中進(jìn)行遍歷、查詢、修改等操作。
import java.io.*;import java.net.*;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.io.SAXReader;public class XMLLoader {private Document doc = null;public void parseWithSAX(File file)throws MalformedURLException, DocumentException {SAXReader xmlReader = new SAXReader();this.doc = xmlReader.read(file);return;}public void parseWithSAX(URL url)throws MalformedURLException, DocumentException {SAXReader xmlReader = new SAXReader();this.doc = xmlReader.read(url);return;}}
QName and Namespace
QName對象表示了一個(gè)XML元素或?qū)傩缘膓ualified name,即一個(gè)namespace和一個(gè)local name的二元組。
Namespace對象表示了QName二元組中的namespace部分,它由prefix和URI兩部分組成。
/******************** SAMPLE XML FILE *************************<heavyz:Samplexmlns:heavyz="http://www.heavyzheng.com/schema/sample.xsd"><heavyz:HelloWorld/></heavyz:Sample>*************************************************************/public void printRootQNameInfo(Document doc) {Element root = doc.getRootElement();QName qname = root.getQName();System.out.println("local name : " + qname.getName());System.out.println("namespace prefix: " + qname.getNamespacePrefix());System.out.println("namespace URI : " + qname.getNamespaceURI());System.out.println("qualified name : " + qname.getQualifiedName());return;}/************************* OUTPUT *****************************localname : Samplenamespace prefix: heavyznamespace URI : http://www.heavyzheng.com/schema/sample.xsdqualified name : heavyz:Sample*************************************************************/
可以調(diào)用Namespace(String prefix, String uri)構(gòu)造方法構(gòu)造一個(gè)新的Namespace對象;也可以調(diào)用Namespace.get(String prefix, String uri)靜態(tài)方法獲得一個(gè)新的Namespace對象。
可以調(diào)用QName(String name)構(gòu)造方法構(gòu)造一個(gè)沒有namespace的qualified name;或者調(diào)用QName(String name, Namespace namespace)構(gòu)造方法構(gòu)造一個(gè)有namespace的qualified name。
Navigating Through an XML Tree
對Document對象調(diào)用getRootElement()方法可以返回代表根節(jié)點(diǎn)的Element對象。擁有了一個(gè)Element對象后,可以對該對象調(diào)用elementIterator()方法獲得它的子節(jié)點(diǎn)的Element對象們的一個(gè)iterator。使用(Element)iterator.next()方法遍歷一個(gè)iterator并把每個(gè)取出的元素轉(zhuǎn)化為Element類型。
通過遞歸的方法,以下代碼可以根據(jù)Document對象打印出完整的XML樹。
public void printXMLTree(Document doc) {Element root = doc.getRootElement();printElement(root,0);return;}private void printElement(Element element, int level) {// print indentfor (int i=0; i<level; i++) {System.out.print(" ");}System.out.println(element.getQualifiedName());Iterator iter = element.elementIterator();while (iter.hasNext()) {Element sub = (Element)iter.next();printElement(sub,level+2);}return;}
Getting Information from an Element
可以通過Element類提供的方法訪問一個(gè)XML元素中含有的信息:
Method | Comment |
getQName() | 元素的QName對象 |
getNamespace() | 元素所屬的Namespace對象 |
getNamespacePrefix() | 元素所屬的Namespace對象的prefix |
getNamespaceURI() | 元素所屬的Namespace對象的URI |
getName() | 元素的local name |
getQualifiedName() | 元素的qualified name |
getText() | 元素所含有的text內(nèi)容,如果內(nèi)容為空則返回一個(gè)空字符串而不是null |
getTextTrim() | 元素所含有的text內(nèi)容,其中連續(xù)的空格被轉(zhuǎn)化為單個(gè)空格,該方法不會返回null |
attributeIterator() | 元素屬性的iterator,其中每個(gè)元素都是Attribute對象 |
attributeValue() | 元素的某個(gè)指定屬性所含的值 |
elementIterator() | 元素的子元素的iterator,其中每個(gè)元素都是Element對象 |
element() | 元素的某個(gè)指定(qualified name或者local name)的子元素 |
elementText() | 元素的某個(gè)指定(qualified name或者local name)的子元素中的text信息 |
getParent | 元素的父元素 |
getPath() | 元素的XPath表達(dá)式,其中父元素的qualified name和子元素的qualified name之間使用"/"分隔 |
isTextOnly() | 是否該元素只含有text或是空元素 |
isRootElement() | 是否該元素是XML樹的根節(jié)點(diǎn) |
要取出Element對象中某個(gè)屬性的信息,可以調(diào)用attributeIterator()方法獲得一個(gè)Attribute對象的iterator,然后再遍歷它。也可以直接調(diào)用attributeValue()方法獲得指定屬性的值。該方法接受四種類型的參數(shù):
- attributeValue(QName qname):通過指定qualified name獲得屬性值,如果無法找到指定的屬性,則返回null。
- attributeValue(QName qname, String defaultValue):通過指定qualified name獲得屬性值,如果無法找到指定的屬性,則返回defaultValue。
- attributeValue(String name):通過指定local name獲得屬性值,而忽略屬性的namespace,如果無法找到指定的屬性,則返回null。
- attributeValue(String name, String defaultValue):通過指定local name獲得屬性值,而忽略屬性的namespace,如果無法找到指定的屬性,則返回defaultValue。
對于一個(gè)Attribute對象,可以使用它的以下方法訪問其中的信息:
Method | Comment |
getQName() | 屬性的QName對象 |
getNamespace() | 屬性所屬的Namespace對象 |
getNamespacePrefix() | 屬性所屬的Namespace對象的prefix |
getNamespaceURI() | 屬性所屬的Namespace對象的URI |
getName() | 屬性的local name |
getQualifiedName() | 屬性的qualified name |
getValue() | 屬性的值 |
Writing an XML Tree to OutputStream
Dom4j通過XMLWriter將由Document對象表示的XML樹寫入一個(gè)文件,并使用OutputFormat格式對象指定寫入的風(fēng)格和編碼方法。調(diào)用OutputFormat.createPrettyPrint()方法可以獲得一個(gè)默認(rèn)的pretty print風(fēng)格的格式對象。對OutputFormat對象調(diào)用setEncoding()方法可以指定XML文件的編碼方法。
public void writeTo(OutputStream out, String encoding)throws UnsupportedEncodingException, IOException {OutputFormat format = OutputFormat.createPrettyPrint();format.setEncoding("gb2312");XMLWriter writer = new XMLWriter(System.out,format);writer.write(doc);writer.flush();return;}
Creating an XML Tree
使用DocumentFactory對象創(chuàng)建一個(gè)空的Document對象。DocumentFactory對象由DocumentFactory.getInstance()靜態(tài)方法產(chǎn)生。對Document對象調(diào)用addElement()方法將創(chuàng)建XML根節(jié)點(diǎn),并將該節(jié)點(diǎn)返回。也可以手工創(chuàng)建一個(gè)Element對象并調(diào)用Document.setRootElement()方法把它設(shè)置為根節(jié)點(diǎn)
import org.dom4j.DocumentFactory;import org.dom4j.Document;import org.dom4j.Element;public class XMLSaver {private DocumentFactory factory = null;private Document doc = null;private Element root = null;public XMLSaver() {factory = DocumentFactory.getInstance();doc = factory.createDocument();}public Element generateRoot(String name) {root = doc.addElement(name);return root;}public Element generateRoot(QName qname) {root = doc.addElement(qname);return root;}public Element generateRoot(Element element) {doc.setRootElement(element);root = element;return root;}}
Adding Information into an Element
Element通過addElement()為自己增加一個(gè)子節(jié)點(diǎn)到當(dāng)前所有子節(jié)點(diǎn)的后面。該方法可以接受三種不同類型的參數(shù):(QName qname)、(String name)或者(String qualifiedName, String namespaceURI)。該方法返回增加的子節(jié)點(diǎn)的Element對象。
Element通過addAttribute()為自己增加屬性。該方法可以接受兩種不同類型的參數(shù):(QName qname, String value)或者(String name, String value)。該方法返回自身的Element對象。
Element通過addText()為自己增加文本內(nèi)容。該方法只接受String類型參數(shù),并返回自身的Element對象。
public void addAuthors(Element bookElement) {Element author1 = bookElement.addElement("author");author1.addAttribute("name","Toby");author1.addAttribute("location","Germany");author1.addText("Tobias Rademacher");Element author2 = bookElement.addElement("author");author2.addAttribute("name","James");author2.addAttribute("name","UK");author2.addText("James Strachan");return;}
Deleting Elements and Attributes
要?jiǎng)h除XML樹上的一棵子樹,首先要找到該子樹的根節(jié)點(diǎn),然后對該節(jié)點(diǎn)調(diào)用detach()方法。注意:如果對根節(jié)點(diǎn)調(diào)用了detach()方法,將導(dǎo)致該XML樹不再完整(一個(gè)XML文件需要有且僅有一個(gè)根節(jié)點(diǎn))。
public void deleteSubtree(Element subtreeRoot) {subtreeRoot.detach();return;}
要清除Element下的所有子節(jié)點(diǎn)(包括Element和text),可以對該Element調(diào)用clearContent()方法。該方法不會清除Element的屬性。
要清除Element下的某個(gè)Attribute,首先要獲得該Attribute對象,然后把它作為參數(shù)調(diào)用Element的remove()方法。
Updating an Attribute
要更新一個(gè)屬性的內(nèi)容,首先要獲得該Attribute對象,然后可以調(diào)用setNamespace()方法更新它所屬的namespace;調(diào)用setValue()方法更新它的屬性值。
Updating an Element‘s Text
可以對一個(gè)Element對象調(diào)用isTextOnly()方法判斷它是否只含有text或者是空節(jié)點(diǎn)。對Element對象調(diào)用addText()方法將把一個(gè)字符串附加到Element中,但不會修改它原來擁有的text或者子節(jié)點(diǎn)。如果Element是isTextOnly(),要修改原來含有的text,可以先調(diào)用clearContent(),再調(diào)用addText()并把新值傳入。
public void updateText(Element element, String newText) {if (element.isTextOnly()) {element.clearContent();element.addText(newText);}return;}