作者 : Nazmul Idris 譯者:wanghuzi
創建于 : May 22, 1999
修改于 : May 23, 1999 5:57 pm
內容列表
--------------------------------------------------------------------------------
為什么他們同時存在
什么是DOM?
什么是SAX?
什么時候使用DOM
什么時候使用SAX
結論
為什么他們同時存在
--------------------------------------------------------------------------------
SAX (Simple API for XML) 和 DOM (Document Object Model) 都是為了讓程序員不用寫一個解析器就可以訪問他們的資料信息。通過利用XML 1.0格式保存信息,以及使用SAX或者DOM APIs你的程序可以使用任何解析器。這是因為使用他們所喜愛的語言開發解析器的開發者必須實現SAX和DOM APIs。 SAX和DOM APIs 對多種語言中都可以實現(Java, C++, Perl, Python, 其它...)。
所以SAX 和 DOM都是為了同樣的目的而存在,這就是使用戶可以利用任何編程語言訪問存入XML文檔中的信息(要有一個那種編程語言的解析器)。雖然他們在提供給你訪問信息的方法上大不相同。
什么是DOM?
--------------------------------------------------------------------------------
DOM 可以讓你以分層次對象模型來訪問儲存在XML文檔中的信息。DOM生成一棵節點樹(以XML文檔的結構和信息為基礎)你可以通過這棵樹來訪問你的信息。在XML文檔中的文本信息轉變成一組樹的節點。請看下圖:
不管你的XML文檔中的信息的類型 (不管是表格數據,或是一列items,或者只是文檔), DOM在你創建一個XML文檔的文檔對象時創建一棵節點樹。 DOM強迫你使用樹狀模型(就像 Swing TreeModel)去訪問你的XML文檔中的信息。這種模式確實不錯因為XML原本就是分層次的。這也是DOM為什么可以把你的信息放到一棵樹中的原因(即使信息是表格式的或者簡單的列表????這里不知道該怎么翻原文是:even if the information is actually tabular or a simple list??????)。
上圖是過分簡單的,因為在DOM中,每一個元素節點實際上都有一系列的其他節點作為它的孩子。這些孩子節點可以包含文本值或者是其他元素節點。乍看起來,通過遍歷訪問一個元素的所有孩子節點來訪問這個節點的值是沒有必要的(舉例來說:節點 "<name> Nazmul </name>", Nazmul是值)。如果每個元素只有值的話,這確實是沒有必要的。但是,元素可能含有文本數據或者其他元素;這是你要在DOM中做額外的工作來獲取元素節點值的原因。 通常當你的文檔中只有純數據時,把所有的數據壓成一個“塊“放到字串中并讓DOM把那個字串當成某個特定元素節點的值返回是適當的。這種方式并不適合如果在你的XML文檔中的數據是個文檔(比如像WORD文檔或者FRAMEMAKER文檔) 在文檔中,元素的順序是非常重要的。對于純數據(像一個數據庫表)元素的順序是不要緊的。 之所以DOM保持從XML文檔中讀出的元素的順序,因為它把所有的事物都當成文檔來處理。 文檔對像模型的叫法由此而來。
如果你計劃用DOM做為JAVA對象模型用于你存儲在XML文檔中的信息,那么你不需要考慮SAX??墒侨绻惆l現DOM不是一個可以用于處理XML文檔信息的好的對象模式,那么你可能想看看SAX了。在一些必須使用自定義對象模型的案例中使用SAX是非常普遍的。說一句讓事情看來有些糊涂的話,你也可以在DOM的基礎之上創建自己的對象模式。面向對象真是個好東東。
什么是SAX?
--------------------------------------------------------------------------------
SAX讓你訪問儲存在XML文檔中的信息,不是通過節點樹,而是一系列的事件。你會問,這有什么益處?回答是,SAX選擇不在XML文檔上創建JAVA對象模型(像DOM做的那樣)。 這樣使得SAX更快, 同時使下面所述成為必要:
創立你自己的自定義對像模型
創建一個監聽SAX事件的類同時創建你自己的對象模型
注意這些步驟對DOM而言是不必要的,因為DOM已經為你創建了一個對象模型(將你的信息用一棵節點樹表示)。
在使用DOM的情況下,解析器做了絕大多數事情, 讀入XML文檔, 在這基礎之上創建JAVA對象模型,然后給你一個對這個對象的引用(一個 Document對象),因而你可以操作使用它。SAX被叫做Simple API for XML不是沒有原因的, 她真的很簡單。 SAX沒有期待解析器去做這么多工作,所有SAX 要求的是解析器應該讀入XML文檔,同時根據所遇到的XML文檔的標簽發出一系列事件。你要自己寫一個XML文檔處理器類(XML document handler class)來處理這些事件,這意味著使所有標簽事件有意義還有用你自己的對象模型創建對象。所以你要完成:
控制所有XML文檔信息的自定義對象模型(或者源文檔在這里的寫法從來沒有見過,或者懷疑源文檔在這里有排版錯誤,先這么翻了)
一個監聽SAX事件(事件由SAX解析器讀取你的XML文檔時產生)的文檔處理器,還有解釋這些事件創建你自定義對象模型中的對象
如果你的對象模型簡單的話那么SAX在運行時會非???。在這種情況下,它會比DOM快,因為它忽略了為你的信息創建一個樹形對象模型的過程。從另一方面來說,你必須寫一個SAX 文檔處理器來解釋所有的SAX事件(這會是一件很繁重的工作)。
什么類型的SAX事件被SAX解析器拋出了哪? 這些事件實際上是非常簡單的。SAX會對每一個開始標簽拋出事件,對每一個結束標簽也是如此。它對#PCDATA和 CDATA 部分同樣拋出事件。你的文檔處理器 (對這些事件的監聽器)要解釋這些事件同時還要在他們基礎之上創建你自定義的對象模型。 你的文檔處理器必須對這些事件做出解釋,同時這些事件發生的順序是非常重要的。SAX同時也對processing instructions, DTDs, comments, 拋出事件. 但是它們在概念上是一樣的, 你的解析器要解釋這些事件(還有這些事件的發生順序)以及使他們有意義。
什么時候使用DOM
--------------------------------------------------------------------------------
如果你的XML文檔包含文檔數據(例如, Framemaker documents stored in XML format), 那么DOM就是你的解決方案的最自然選擇。如果你要創建一些類似于文檔信息管理的系統,那么你不得不處理大量的文檔數據。Datachannel RIO 產品就是這么一個例子,它可以索引和組織各種類型文檔資源中的信息(例如Word和Excel 文件)。在這種情況下,DOM是非常合適程序去訪問存貯在這些文檔中的信息的。
然而,如果你主要處理的是結構化的數據(在XML中的序列化的JAVA對象the equivalent of serialized Java objects in XML),DOM不是最好的選擇。那就是SAX會比較合適的地方。
什么時候使用SAX
--------------------------------------------------------------------------------
如果在你XML文檔中的信息是機器易讀的(和機器生成的)數據,那么SAX是讓你可以訪問這些信息的合適的API。機器易讀和生成的數據類型包含像下面這些東東:
存成XML格式的Java對象屬性
用一些以文本為基礎的查詢語句(SQL, XQL, OQL)表示的查詢
由查詢生成的結果集(這也許包含關系型數據庫表中的數據編碼成XML).
這么看來機器生成的數據是你一般要在java中生成數據結構和類的信息。一個簡單的例子是包含個人信息的地址簿,在上圖所示。這個地址簿xml文件不像字處理器文檔,它是一個包含已經被編碼成文本的純數據的XML文檔。
當你的數據是這種樣式,你要創建你自己的數據結構和類(對象模型)來管理操作以及持續保存這些數據。SAX容許你快速創建一個可以生成你的對象模型實例的處理器類。一個實例是:一個SAX文檔處理器。它完成的工作有讀入包含我的地址薄信息的XML文檔,創建一個可以訪問到這些信息的AddressBook類。SAX指南告訴你該怎么做到這些。這個地址薄XML文檔包含person元素,person元素中有name和email元素。我的AddressBook對象模型包括下面的類:
AddressBook 類,Person對象的容器
Person 類,String 型的name和email的容器
這樣我的“SAX 地址簿文檔處理器”可以把person元素轉變成Person對象了,然后把它們都存入AddressBook對象。這個文檔處理器將name和email元素轉變為String對象。
結論
--------------------------------------------------------------------------------
你寫的SAX文檔處理器(SAX document handler)做了將元素映射為對象的工作。如果你的信息被結構化成可以容易創建這樣的映射,你應該使用SAX API。從另一方面來說,如果你的數據更適宜用樹來表示那么你應該使用DOM。