DOM是標(biāo)準(zhǔn)的樹結(jié)構(gòu),其中每個節(jié)點(diǎn)包含來自XML結(jié)構(gòu)的一個組件。
XML文檔中兩種最常見的節(jié)點(diǎn)類型是元素節(jié)點(diǎn)和文本節(jié)點(diǎn)。
使用Java DOM API,我們可以創(chuàng)建節(jié)點(diǎn),刪除節(jié)點(diǎn),更改其內(nèi)容,并遍歷節(jié)點(diǎn)層次結(jié)構(gòu)。
文檔對象模型標(biāo)準(zhǔn)是為XML文檔操作而設(shè)計的。
DOM的用意是語言無關(guān)的。Java的DOM解析器沒有利用Java的面向?qū)ο蟮奶匦?/span>優(yōu)勢。
文本和元素在DOM層次結(jié)構(gòu)中混合。這種結(jié)構(gòu)在DOM模型中稱為混合內(nèi)容。
例如,我們有以下xml結(jié)構(gòu):
<yourTag>This is an <bold>important</bold> test.</yourTag>
DOM節(jié)點(diǎn)的層級如下,其中每行代表一個節(jié)點(diǎn):
ELEMENT: yourTag + TEXT: This is an + ELEMENT: bold + TEXT: important + TEXT: test.
yourTag
元素包含文本,后跟一個子元素,后跟另外的文本。
為了支持混合內(nèi)容,DOM節(jié)點(diǎn)非常簡單。標(biāo)簽元素的“內(nèi)容"標(biāo)識它是的節(jié)點(diǎn)的類型。
例如,<yourTag> 節(jié)點(diǎn)內(nèi)容是元素 yourTag
的名稱。
DOM節(jié)點(diǎn)API定義 nodeValue()
, nodeType()
和 nodeName()
方法。
對于元素節(jié)點(diǎn)< yourTag>
nodeName()返回yourTag,而nodeValue()返回null。
對于文本節(jié)點(diǎn) + TEXT:這是一個
nodeName()返回#text,nodeValue()返回“This is an"。
以下代碼顯示了如何使用DOM解析器來解析xml文件并獲取一個 org.w3c.dom.Document
對象。
import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; public class Main { public static void main(String[] args) throws Exception { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = null; db = dbf.newDocumentBuilder(); Document doc = db.parse(new File("games.xml")); } }
以下代碼顯示如何執(zhí)行DOM轉(zhuǎn)儲。
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; public class Main{ static public void main(String[] arg) throws Exception{ String filename = "input.xml"; boolean validate = true; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setValidating(validate); dbf.setNamespaceAware(true); dbf.setIgnoringElementContentWhitespace(true); DocumentBuilder builder = dbf.newDocumentBuilder(); builder.setErrorHandler(new MyErrorHandler()); InputSource is = new InputSource(filename); Document doc = builder.parse(is); TreeDumper td = new TreeDumper(); td.dump(doc); } } class TreeDumper { public void dump(Document doc) { dumpLoop((Node)doc,""); } private void dumpLoop(Node node,String indent) { switch(node.getNodeType()) { case Node.CDATA_SECTION_NODE: System.out.println(indent + "CDATA_SECTION_NODE"); break; case Node.COMMENT_NODE: System.out.println(indent + "COMMENT_NODE"); break; case Node.DOCUMENT_FRAGMENT_NODE: System.out.println(indent + "DOCUMENT_FRAGMENT_NODE"); break; case Node.DOCUMENT_NODE: System.out.println(indent + "DOCUMENT_NODE"); break; case Node.DOCUMENT_TYPE_NODE: System.out.println(indent + "DOCUMENT_TYPE_NODE"); break; case Node.ELEMENT_NODE: System.out.println(indent + "ELEMENT_NODE"); break; case Node.ENTITY_NODE: System.out.println(indent + "ENTITY_NODE"); break; case Node.ENTITY_REFERENCE_NODE: System.out.println(indent + "ENTITY_REFERENCE_NODE"); break; case Node.NOTATION_NODE: System.out.println(indent + "NOTATION_NODE"); break; case Node.PROCESSING_INSTRUCTION_NODE: System.out.println(indent + "PROCESSING_INSTRUCTION_NODE"); break; case Node.TEXT_NODE: System.out.println(indent + "TEXT_NODE"); break; default: System.out.println(indent + "Unknown node"); break; } NodeList list = node.getChildNodes(); for(int i=0; i<list.getLength(); i++) dumpLoop(list.item(i),indent + " "); } } class MyErrorHandler implements ErrorHandler { public void warning(SAXParseException e) throws SAXException { show("Warning", e); throw (e); } public void error(SAXParseException e) throws SAXException { show("Error", e); throw (e); } public void fatalError(SAXParseException e) throws SAXException { show("Fatal Error", e); throw (e); } private void show(String type, SAXParseException e) { System.out.println(type + ": " + e.getMessage()); System.out.println("Line " + e.getLineNumber() + " Column " + e.getColumnNumber()); System.out.println("System ID: " + e.getSystemId()); } }
以下代碼顯示了如何在使用DOM解析器解析XML時處理錯誤。
import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; public class DOMCheck { static public void main(String[] arg) { boolean validate = true; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setValidating(validate); dbf.setNamespaceAware(true); try { DocumentBuilder builder = dbf.newDocumentBuilder(); builder.setErrorHandler(new MyErrorHandler()); InputSource is = new InputSource("person.xml"); Document doc = builder.parse(is); } catch (SAXException e) { System.out.println(e); } catch (ParserConfigurationException e) { System.err.println(e); } catch (IOException e) { System.err.println(e); } } } class MyErrorHandler implements ErrorHandler { public void warning(SAXParseException e) throws SAXException { show("Warning", e); throw (e); } public void error(SAXParseException e) throws SAXException { show("Error", e); throw (e); } public void fatalError(SAXParseException e) throws SAXException { show("Fatal Error", e); throw (e); } private void show(String type, SAXParseException e) { System.out.println(type + ": " + e.getMessage()); System.out.println("Line " + e.getLineNumber() + " Column " + e.getColumnNumber()); System.out.println("System ID: " + e.getSystemId()); } }
以下代碼顯示了如何遞歸訪問DOM樹中的所有節(jié)點(diǎn)。
import java.io.File; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Main { public static void main(String[] argv) throws Exception{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); factory.setExpandEntityReferences(false); Document doc = factory.newDocumentBuilder().parse(new File("file.xml")); visit(doc, 0); } public static void visit(Node node, int level) { NodeList list = node.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node childNode = list.item(i); visit(childNode, level + 1); } } }
下面的代碼顯示了如何將XML片段轉(zhuǎn)換為DOM片段。
import java.io.File; import java.io.StringReader; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.DocumentFragment; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xml.sax.InputSource; public class Main { public static void main(String[] argv) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); Document doc = factory.newDocumentBuilder().parse(new File("infilename.xml")); String fragment = "<fragment>aaa</fragment>"; factory = DocumentBuilderFactory.newInstance(); Document d = factory.newDocumentBuilder().parse(new InputSource(new StringReader(fragment))); Node node = doc.importNode(d.getDocumentElement(), true); DocumentFragment docfrag = doc.createDocumentFragment(); while (node.hasChildNodes()) { docfrag.appendChild(node.removeChild(node.getFirstChild())); } Element element = doc.getDocumentElement(); element.appendChild(docfrag); } }
下面的代碼顯示了如何解析XML字符串:使用DOM和StringReader。
import java.io.StringReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.CharacterData; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; public class Main { public static void main(String arg[]) throws Exception{ String xmlRecords = "<data><employee><name>A</name>" + "<title>Manager</title></employee></data>"; DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); InputSource is = new InputSource(); is.setCharacterStream(new StringReader(xmlRecords)); Document doc = db.parse(is); NodeList nodes = doc.getElementsByTagName("employee"); for (int i = 0; i < nodes.getLength(); i++) { Element element = (Element) nodes.item(i); NodeList name = element.getElementsByTagName("name"); Element line = (Element) name.item(0); System.out.println("Name: " + getCharacterDataFromElement(line)); NodeList title = element.getElementsByTagName("title"); line = (Element) title.item(0); System.out.println("Title: " + getCharacterDataFromElement(line)); } } public static String getCharacterDataFromElement(Element e) { Node child = e.getFirstChild(); if (child instanceof CharacterData) { CharacterData cd = (CharacterData) child; return cd.getData(); } return ""; } }
上面的代碼生成以下結(jié)果。
更多建議: