【正文】
04: author陳會(huì)安 /author 05: price650/price 06: /book 07: /library XML的 DOM樹 ? 以 W3C DOM 的角度來看,前頁(yè)的 XML 文件就是一棵樹狀結(jié)構(gòu)的節(jié)點(diǎn)資料,以 Java 語言來說,就是一個(gè) Document 物件,如下圖所示: 什麼是 JAXP ? 之前已經(jīng)說過了,要處理 XML 文件,首先這份文件都必須先經(jīng)過 parser 來解析。 ?事件基礎(chǔ)的剖析器( Eventbased Parser): ? 讀取內(nèi)容時(shí)觸發(fā)一系列事件,應(yīng)用程式提供函數(shù)處理這些事件,以便存取 XML內(nèi)容,例如: SAX( Simple API for XML)。 Parsing Events ? View the XML document as a stream of events: ? the document starts ? a start tag is encountered ? an end tag is encountered ? a namespace declaration is seen ? some whitespace is seen ? character data is encountered ? the document ends ? The SAX tool observes these events ? It reacts by calling corresponding methods specified by the programmer DOM vs. SAX ? Memory consumption: ?The JDOM version: on 18MB document ?The SAX version handles in 51 seconds ? Tree Navigation is easier for DOM。 ? XML 的 parser 有非常多種,比較著名的有 Apache 的 Xerces、 Crimson 等;只可惜這些 parser 所提供的 APIs 並不相通(這跟當(dāng)初設(shè)計(jì) DOM APIs 時(shí)的想法不同)。 ? SAXParserFactory類別:可以取得 SAXParser 實(shí)例來處理 SAX 事件基礎(chǔ)的 XML 剖析。 ?程式碼匯入 XML 剖析器和 DOM 的相關(guān)套件,至於 .* 套件是剖析錯(cuò)誤處理的相關(guān)套件。 try { DocumentBuilder db = ()。 } catch(IOException ie) { ()。 使用 DTD驗(yàn)證 ? JAXP 從 API 版就開始支援 DTD 驗(yàn)證, 只需在 DocumentBuilderFactory 物件使用setValidating() 方法設(shè)定參數(shù)為 true,就可以驗(yàn)證 XML文件,如下所示: (true)。 import .*。 // 設(shè)定剖析的參數(shù) (false)。 // 剖析 XML文件 (new File(filename))。 } catch(SAXException se) { (“XML剖析 錯(cuò)誤 )。 import .*。 public static void main(String[] args) { String filename = 。 // 讀入 XML文件 document = (new File(filename))。 讀取 的內(nèi)容,並將每一個(gè)節(jié)點(diǎn)的節(jié)點(diǎn)型態(tài)、節(jié)點(diǎn)名稱等依照樹狀結(jié)構(gòu)列印出來。 pChild(child, 0)。// 檔案處理錯(cuò)誤 } } Ch10_3_1 修改版 // 練習(xí)題:請(qǐng)補(bǔ)上其他的節(jié)點(diǎn)型態(tài) // 程設(shè)的補(bǔ)充:這就是多型的應(yīng)用 private static String getID(Node n) { int type = ()。 case 6: return 實(shí)體名稱: + ()。 default: return 尚未定義: + type。 i++) { int type = (i).getNodeType()。 } } } } // 顯示縮排所需的字元 private static void printIndent(int num) { ( +)。 } } Node節(jié)點(diǎn)種類 ge tN o d e Typ e () N o d e 種類 ge tN o d e N am e () ge tN o d e V al u e () ge tA ttr i b u te s () 2 A t t r 屬性 屬性名稱 屬性值 n u l l 4 CD A T A S e c t i o n c da t a s e c t i o n CD A T A 值 n u l l 8 Co m m e n t 註解 c o m m e n t 註解文字內(nèi)容 n u l l 9 D o c um e n t 文件 do c um e n t n u l l n u l l 11 D o c um e n t F ra g m e nt do c um e n t f ra g m e nt n u l l n u l l 10 !D O CT Y P E n u l l n u l l n u l l 1 E l e m e n t 標(biāo)籤名稱 n u l l N a m e dN o de M a p 3 T e xt t e xt 文字內(nèi)容 n u l l 5 E n t i t y R e fe r e n c e 實(shí)體參考名稱 n u l l n u l l 6 E n t i t y 實(shí)體名稱 n u l l n u l l 7 PI t a r ge t 不包含 t a r ge t 的內(nèi)容 n u l l 12 N o t a t i o n N o t a t i o n 名稱 n u l l n u l l Document文件物件 ? XML 文件建立的樹狀結(jié)構(gòu)是 Document 物件(可以想成之前說過的 root node) ? 當(dāng) DOM 載入 XML 文件建立 Document 物件後,就可以使用 getDocumentElement() 方法取得 XML 文件的根元素,如下所示: ? Node root = ()。 ?另外,還有 getNodeValue() 和 getAttributes() Node 節(jié)點(diǎn)物件 ? Node 節(jié)點(diǎn)物件還提供更多方法能夠?yàn)g覽XML 文件來取得指定節(jié)點(diǎn),相關(guān)方法的說明,如下表所示: 方法 說明get F ir st C h ild () 取得第一個(gè)子節(jié)點(diǎn)get L a s tCh ild () 取得最後一個(gè)子節(jié)點(diǎn)get N e x tSi b ling () 取得下一個(gè)兄弟節(jié)點(diǎn) ,兩個(gè)節(jié)點(diǎn)擁有相同的父節(jié)點(diǎn)稱為兄弟節(jié)點(diǎn)get P ar e nt N od e () 取得父節(jié)點(diǎn)NodeList 節(jié)點(diǎn)清單的集合物件 ? 當(dāng)在 Java 程式呼叫 getChildNodes() 方法,或是 getElementByTagName() 方法取得指定節(jié)點(diǎn)時(shí),這些節(jié)點(diǎn)是一個(gè) NodeList 集合物件(也就是類似 List 的結(jié)構(gòu)),而每一個(gè)節(jié)點(diǎn)包含該節(jié)點(diǎn)和其子節(jié)點(diǎn)的一棵子樹。 i ()。 Element元素物件 ? Element 物件代表樹狀結(jié)構(gòu)的 XML 元素節(jié)點(diǎn): ? NodeList tagNodes = (book)。 NamedNodeMap 集合物件 ? NamedNodeMap 集合物件是元素的屬性集合(類似 Map 的結(jié)構(gòu))。 j++) { Node att = (j)。 ? 我們先以建立新的 DOM 為例 ?建立新的 XML DOM 的語法如下: DocumentBuilder db = ()。(只需把 newDocument() 換成 parse() 並找到必要的 context node) 新增 XML元素和屬性 步驟一 第一步:建立新節(jié)點(diǎn) ? 使用 Document 物件的相關(guān)方法來建立所需的節(jié)點(diǎn)物件 ? 例如:在新建立的 XML DOM 新增元素,如下所示 : (請(qǐng)注意:只是新增節(jié)點(diǎn),該節(jié)點(diǎn)與 document 之間暫時(shí)還沒有關(guān)係) Element root = (Element) (book)。 ? 例如:將 root 節(jié)點(diǎn)新增成為 XML DOM 的根節(jié)點(diǎn),如下所示: (root)。 (node)。 ? 如果想刪除屬性,則是使用 Element 元素物件的removeAttribute() 方法來刪除屬性,如下所示: // 取得一個(gè) Element 節(jié)點(diǎn) del (instock)。 Attr attr = (instock)。 (element, (), “books”)。 import .*。 // 建立新 XML文件 document = ()。 (node)。 ((PHP 5網(wǎng)頁(yè)設(shè)計(jì)範(fàn)例教本 ))。 ().appendChild(newText)。 printXML(root)。 (刪除後的 XML文件 : )。 // 取得所有的子節(jié)點(diǎn) for ( int i=0。 // 顯示指定元素的屬性值 if ((i).hasAttributes()) { NamedNodeMap atts = (i).getAttributes()。 ( + +())。 NodeList nodes = ()。 (/+(i).getFirstChild().getNodeValue())。 j++) { Node att = (j)。 } } 練習(xí)題 ? 請(qǐng)修改 Ch10_4_1 並使其能夠產(chǎn)生 的 XML 文件。 import .*。 (1)。 } } TestXSD public TestXSD(String xmlFile) throws ParserConfigurationException, SAXException, IOException { DocumentBuilderFactory factory = ()。 // 明確告知 JAXP 所使用的 Schema 語言 ( // Specify our own schema this overrides the schemaLocation in the xml file //( file:./)。 Node rootNode = ()。 public class SimpleErrorHandler implements ErrorHandler { public void error(SAXParseException exception) { (error: + ())。 (true)。 // 利用 XPathFactory 產(chǎn)生 XPath 處理器 XPath xpath = ()。 import .*。 public class TestXPath {