国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

在Java中使用DOM和XPath進行有效的XML處理

開發 后端
在對幾個大型 XML 項目分析的基礎上,本文探討了在 Java 中如何有效和高效的使用 DOM。DOM 為創建、處理和操縱 XML 文檔提供了靈活和有效的方法,但使用起來可能比較困難并且可能導致不穩定和錯誤的代碼。作者 Parand Tony Daruger 提供了一套 Java 用法模式和函數庫,使 DOM 變得健壯且易于使用。

文檔對象模型(Document Object Model,DOM)是公認的 W3C 標準,它被用于與平臺及語言無關的 XML 文檔內容、結構和樣式的動態訪問和更新。它為表示文檔定義了一套標準的接口集,也為訪問和操縱文檔定義了一套標準的方法。DOM 得到廣泛的支持和普及,并且它以各種不同的語言實現,包括 Java、Perl、C、C++、VB、Tcl 和 Python。

正如我將在本文所演示的,當基于流的模型(例如 SAX)不能滿足 XML 處理要求時,DOM 是一個***的選擇。不幸的是,規范的幾個方面,例如其語言無關性接口和“一切都是節點(everything-is-a-node)”抽象概念的使用,使其難以使用且易于生成脆弱代碼。這在最近的幾個大型 DOM 項目的研究中尤其明顯,這些項目是由許多開發人員過去一年所創建的。下面討論了常見的問題及其補救措施。

文檔對象模型

DOM 規范被設計成可與任何編程語言一起使用。因此,它嘗試使用在所有語言中都可用的一組通用的、核心的功能部件。DOM 規范同樣嘗試保持其接口定義方面的無關性。這就允許 Java 程序員在使用 Visual Basic 或 Perl 時應用他們的 DOM 知識,反之亦然。

該規范同樣將文檔的每個部分看成由類型和值組成的節點。這為處理文檔的所有方面提供了***的概念性框架。例如,下面的 XML 片段

the Italicized portion.

就是通過以下的 DOM 結構表示的:

圖 1:XML 文檔的 DOM 表示

樹的每個Document 、 Element 、 Text 和 Attr 部分都是 DOM Node 。

***的抽象確實付出了代價。考慮 XML 片段: Value 。您或許會認為文本的值可以通過普通的 Java String 對象來表示,并且通過簡單的 getValue 調用可訪問。實際上,文本被當成 tagname 節點下的一個或多個子 Node 。因此,為了獲取文本值,您需要遍歷 tagname 的子節點,將每個值整理成一個字符串。這樣做有充分的理由: tagname 可能包含其它嵌入的 XML 元素,在這種情況下獲取其文本值沒有多大意義。然而,在現實世界中,我們看到由于缺乏便利的函數導致頻繁的編碼錯誤占了 80% 的情況,這樣做的確有意義。

設計問題

DOM 語言無關性的缺點是通常在每個編程語言中使用的一整套工作方法和模式不能被使用。例如,不能使用熟悉的 Java new 構造創建新的 Element ,開發者必須使用工廠構造器方法。 Node 的集合被表示成 NodeList ,而不是通常的 List 或 Iterator 對象。這些微小的不便意味著不同尋常的編碼實踐和增多的代碼行,并且它們迫使程序員學習 DOM 的行事方法而不是用直覺的方法。

DOM 使用“一切都是節點”的抽象。這就意味著幾乎 XML 文檔的每個部分,例如: Document 、 Element 和 Attr ,全都繼承( extend ) Node 接口。這不僅是概念上***,而且還允許每個 DOM 的不同實現通過標準接口使其自身的類可見,并且沒有通過中間包裝類所導致的性能損失。

由于存在的節點類型數量及其訪問方法缺乏一致性,“一切都是節點”的抽象喪失了一些意義。例如, insertData 方法被用來設置 CharacterData 節點的值,而通過使用 setValue 方法來設置 Attr (屬性)節點的值。由于對于不同的節點存在不同的接口,模型的一致性和***性降低了,而學習曲線增加了。

#p#

JDOM

JDOM 是使 DOM API 適應 Java 的研究計劃,從而提供了更自然和易用的接口。由于認識到語言無關 DOM 構造的棘手本質,JDOM 目標在于使用內嵌的 Java 表示和對象,并且為常用任務提供便利的函數。

例如,JDOM 直接處理“一切都是節點”和 DOM 特定構造的使用(如 NodeList )。JDOM 將不同的節點類型(如 Document 、 Element 和 Attribute )定義為不同的 Java 類,這意味著開發者可以使用 new 構造它們,避免頻繁類型轉換的需要。JDOM 將字符串表示成 Java String ,并且通過普通的 List 和 Iterator 類來表示節點的集合。(JDOM 用其本身類替代 DOM 類。)

JDOM 為提供更完善的接口做了相當有益的工作。它已經被接受成為 JSR(正式的 Java Specification Request),而且它將來很可能會被包含到核心的 Java 平臺中。但是,因其還不是核心 Java API 的一部分,一些人對于使用它還心存猶豫。這兒還有關于與 Iterator 和 Java 對象頻繁創建相關的性能問題的報告。(請參閱 參考資料)。

如果您對 JDOM 的接受性和可用性已經滿足,并且如果您也沒有將 Java 代碼和程序員轉移到其它語言的直接需求,JDOM 是個值得探索的好選擇。JDOM 還不能滿足本文探討的項目所在的公司需要,因而他們使用了非常普遍的 DOM。本文也是這樣做的。

常見編碼問題

幾個大型 XML 項目分析揭示了使用 DOM 中的一些常見問題。下面對其中的幾個進行介紹。

代碼臃腫

在我們研究中查看的所有項目,本身都出現一個突出的問題:花費許多行代碼行來做簡單的事情。在某個示例中,使用 16 行代碼檢查一個屬性的值。而同樣的任務,帶有改進的健壯性和出錯處理,可以使用 3 行代碼實現。DOM API 的低級本質、方法和編程模式的不正確應用以及缺乏完整 API 的知識,都會致使代碼行數增加。下面的摘要介紹了關于這些問題的特定實例。

遍歷 DOM

在我們探討的代碼中,最常見的任務是遍歷或搜索 DOM。 清單 1 演示了需要在文檔的 config 節里查找一個稱為“header”節點的濃縮版本代碼:

清單 1 中,從根開始通過檢索頂端元素遍歷文檔,獲取其***個子節點( configNode ),并且最終單獨檢查 configNode 的子節點。不幸的是,這種方法不僅冗長,而且還伴隨著脆弱性和潛在的錯誤。

例如,第二行代碼通過使用 getFirstChild 方法獲取中間的 config 節點。已經存在許多潛在的問題。根節點的***個子節點實際上可能并不是用戶正在搜索的節點。由于盲目地跟隨***個子節點,我忽視了標記的實際名稱并且可能搜索不正確的文檔部分。當源 XML 文檔的根節點后包含空格或回車時,這種情況中發生一個頻繁的錯誤;根節點的***個子節點實際是 Node.TEXT_NODE 節點,而不是所希望的元素節點。您可以自己試驗一下,從 參考資料下載樣本代碼并且編輯 sample.xml 文件 ― 在 sample 和 config 標記之間放置一個回車。代碼立即異常而終止。要正確瀏覽所希望的節點,需要檢查每個 root 的子節點,直到找到非 Text 的節點,并且那個節點有我正在查找的名稱為止。

清單 1 還忽視了文檔結構可能與我們期望有所不同的可能性。例如,如果 root 沒有任何子節點, configNode 將會被設置為 null ,并且示例的第三行將產生一個錯誤。因此,要正確瀏覽文檔,不僅要單獨檢查每個子節點以及核對相應的名稱,而且每步都得檢查以確保每個方法調用返回的是一個有效值。編寫能夠處理任意輸入的健壯、無錯的代碼,不僅需要非常關注細節,而且需要編寫很多行代碼。

最終,如果最初的開發者了解它的話,清單 1 中示例的所有功能應該可以通過利用對 getElementsByTagName 函數的簡單調用實現。這是下面要討論的。

檢索元素中的文本值

在所分析的項目中,DOM 遍歷以后,第二項最常進行的任務是檢索在元素中包含的文本值。考慮 XML 片段 The Value 。如果已經導航到 sometag 節點,如何獲取其文本值( The Value )呢?一個直觀的實現可能是:

sometagElement.getData();

正如您所猜測到的,上面的代碼并不會執行我們希望的動作。由于實際的文本被存儲為一個或多個子節點,因此不能對 sometag 元素調用 getData 或類似的函數。更好的方法可能是:

sometag.getFirstChild().getData();

第二種嘗試的問題在于值實際上可能并不包含在***個子節點中;在 sometag 內可能會發現處理指令或其它嵌入的節點,或是文本值包含在幾個子節點而不是單單一個子節點中。考慮到空格經常作為文本節點表示,因此對 sometag.getFirstChild() 的調用可能僅讓您得到標記和值之間的回車。實際上,您需要遍歷所有子節點,以核對 Node.TEXT_NODE 類型的節點,并且整理它們的值直到有完整的值為止。

注意,JDOM 已經利用便利的函數 getText 為我們解決了這個問題。DOM 級別 3 也將有一個使用規劃的 getTextContent 方法的解答。教訓:盡可能使用較高級的 API 是不會錯的。

getElementsByTagName

DOM 級別 2 接口包含一個查找給定名稱的子節點的方法。例如,調用:

NodeList names = someElement.getElementsByTagName("name");

將返回一個包含在 someElement 節點中稱為 names 的節點 NodeList 。這無疑比我所討論的遍歷方法更方便。這也是一組常見錯誤的原因。

問題在于 getElementsByTagName 遞歸地遍歷文檔,從而返回所有匹配的節點。假定您有一個包含客戶信息、公司信息和產品信息的文檔。所有這三個項中都可能含有 name 標記。如果調用 getElementsByTagName 搜索客戶名稱,您的程序極有可能行為失常,除了檢索出客戶名稱,還會檢索出產品和公司名稱。在文檔的子樹上調用該函數可能會降低風險,但由于 XML 的靈活本質,使確保您所操作的子樹包含您期望的結構,且沒有您正在搜索的名稱的虛假子節點就變得十分困難。

#p#

DOM 的有效使用

考慮到由 DOM 設計強加的限制,如何才能有效和高效的使用該規范呢?下面是使用 DOM 的幾條基本原則和方針,以及使工作更方便的函數庫。

基本原則

如果您遵循幾條基本原則,您使用 DOM 的經驗將會顯著提高:

◆ 不要使用 DOM 遍歷文檔。

◆ 盡可能使用 XPath 來查找節點或遍歷文檔。

◆ 使用較高級的函數庫來更方便地使用 DOM。

這些原則直接從對常見問題的研究中得到。正如上面所討論的,DOM 遍歷是出錯的主要原因。但它也是最常需要的功能之一。如何通過不使用 DOM 而遍歷文檔呢?

Path

XPath 是尋址、搜索和匹配文檔的各個部分的語言。它是 W3C 推薦標準(Recommendation),并且在大多數語言和 XML 包中實現。您的 DOM 包可能直接支持 XPath 或通過加載件(add-on)支持。本文的樣本代碼對于 XPath 支持使用 Xalan 包。

XPath 使用路徑標記法來指定和匹配文檔的各個部分,該標記法與文件系統和 URL 中使用的類似。例如,XPath: /x/y/z 搜索文檔的根節點 x ,其下存在節點 y ,其下存在節點 z 。該語句返回與指定路徑結構匹配的所有節點。

更為復雜的匹配可能同時在包含文檔的結構方面以及在節點及其屬性的值中。語句 /x/y/* 返回父節點為 x 的 y 節點下的任何節點。 /x/y[@name='a'] 匹配所有父節點為 x 的 y 節點,其屬性稱為 name ,屬性值為 a 。請注意,XPath 處理篩選空格文本節點以獲得實際的元素節點 ― 它只返回元素節點。

詳細探討 XPath 及其用法超出了本文的范圍。請參閱 參考資料獲得一些優秀教程的鏈接。花點時間學習 XPath,您將會更方便的處理 XML 文檔。

函數庫

當研究 DOM 項目時令我們驚奇的一個發現,是存在的拷貝和粘貼代碼的數量。為什么有經驗的開發者沒有使用良好的編程習慣,卻使用拷貝和粘貼方法而不是創建助手(helper)庫呢?我們相信這是由于 DOM 的復雜性加深了學習的難度,并使開發者要理解能完成他們所需要的***段代碼。開發產生構成助手庫規范的函數所需的專門技術需要花費大量的時間。

要節省一些走彎路的時間,這里是一些將使您自己的庫可以運轉起來的基本助手函數。

findValue

使用 XML 文檔時,最常執行的操作是查找給定節點的值。正如上所討論的,在遍歷文檔以查找期望的值和檢索節點的值中都出現難度。可以通過使用 XPath 來簡化遍歷,而值的檢索可以一次編碼然后重用。在兩個較低級函數的幫助下,我們實現了 getValue 函數,這兩個低級函數是:由 Xalan 包提供的 XPathAPI.selectSingleNode (用來查找和返回與給定的 XPath 表達式匹配的***個節點);以及 getTextContents ,它非遞歸地返回包含在節點中的連續文本值。請注意,JDOM 的 getText 函數,或將出現在 DOM 級別 3 中規劃的 getTextContent 方法,都可用來代替 getTextContents 。 清單 2包含了一個簡化的清單;您可以通過下載樣本代碼來訪問所有函數(請參閱 參考資料)。

通過同時傳入要開始搜索的節點和指定要搜索節點的 XPath 語句來調用 findValue 。函數查找***個與給定 XPath 匹配的節點,并且抽取其文本值。

setValue

另一項常用的操作是將節點的值設置為希望的值,如 清單 3 所示。該函數獲取一個起始節點和一條 XPath 語句 ― 就象 findValue ― 以及一個用來設置匹配的節點值的字符串。它查找希望的節點,除去其所有子節點(因此除去包含在其中的任何文本和其它元素),并將其文本內容設置為傳入的(passed-in)字符串。

appendNode

雖然某些程序查找和修改包含在 XML 文檔中的值,而另一些則通過添加和除去節點來修改文檔本身的結構。這個助手函數簡化了文檔節點的添加,如 清單 4所示。

該函數的參數有:要將新節點添加到其下的節點,要添加的新節點名稱,以及指定要將節點添加到其下位置的 XPath 語句(也就是,新節點的父節點應當是哪個)。新節點被添加到文檔的指定位置。

最終分析

DOM 的語言無關性設計為其帶來了非常廣泛的可應用性并使其在大量的系統和平臺上得以實現。這樣做的代價是:使 DOM 比為每個語言專門設計的 API 更困難且更缺乏直觀性。

DOM 奠定了一個非常有效的基礎,遵循一些簡單的原則就可其上構建易于使用的系統。凝結了一大群用戶智慧和經驗的 DOM 未來版本正在設計之中,而且極有可能為這里討論的問題提供解決方案。如 JDOM 這樣的項目正在修改該 API 以獲得更自然 Java 感覺,而且如本文中所述的技術可以幫助您使 XML 的操縱更方便、更簡潔并且不易出錯。利用這些項目且遵循這些用法模式以允許 DOM 成為基于 XML 項目的出色平臺。

【編輯推薦】

  1. 如何使用C#與XML創建動態分層菜單
  2. 在ASP.NET中使用Treeview控件和XML
  3. 使用 XStream 把 Java 對象序列化為 XML
責任編輯:楊鵬飛 來源: ibm
相關推薦

2011-12-08 10:24:53

JavaNIO

2009-02-05 13:40:03

TreeviewXMLASP.NET

2009-02-10 09:23:03

DOM模型MSXML

2010-09-28 11:11:23

XML DOMHTML DOM

2009-06-23 14:22:00

DOM文檔XML文件Java

2021-09-21 15:44:02

LinuxOBSWayland

2021-06-22 10:30:42

Linuxpushdpopd

2012-03-14 11:38:16

ibmdw

2021-11-29 22:59:34

Go Dockertest集成

2024-02-07 11:44:20

NestJSRxJS異步編程

2023-10-28 16:22:21

Go接口

2009-06-19 16:29:47

EJBXML

2013-06-08 13:29:27

Android開發DOM讀取XMLXML解析

2009-04-02 17:37:38

dom4jXMLJava

2009-12-28 13:59:12

ADO調用存儲過程

2021-12-24 11:25:37

FreeDOS批處理文件Linux

2020-10-25 11:33:57

PythonKNN算法

2023-05-24 16:41:41

React前端

2019-12-12 13:50:27

strace追蹤系統調用Linux

2021-07-29 10:00:43

XMLXMLStarletLinux
點贊
收藏

51CTO技術棧公眾號

日韩av大片免费看| 日韩视频一区在线观看| 日韩在线免费视频观看| 青草全福视在线| 91亚洲国产高清| 精品国产一二三| 九色91popny| 欧美一级播放| 久久精品99无色码中文字幕| 国产欧美精品aaaaaa片| 午夜日韩激情| 欧美在线一区二区三区四| 国产高清在线a视频大全| 一区二区三区四区在线播放 | 久久久久北条麻妃免费看| 男人天堂免费视频| 亚洲色诱最新| 日韩成人中文字幕在线观看| 蜜桃av久久久亚洲精品| 精品国产白色丝袜高跟鞋| 国产午夜视频| 国产一级精品aaaaa看| 韩国日本不卡在线| 日本精品裸体写真集在线观看| 国产成人福利av| 欧美色综合网站| 国产午夜精品美女视频明星a级| 欧美日韩精品一区二区三区在线观看| 自拍偷拍亚洲综合| 国产一区二区免费电影| 91在线成人| 亚洲激情自拍图| 日韩欧美在线观看一区二区| 成人国产精品视频| 亚洲欧美日产图| 久久综合亚州| 国内精久久久久久久久久人| 一二三在线视频社区| 亚洲国产日韩综合久久精品| 亚洲中文字幕久久精品无码喷水| 免费看欧美女人艹b| 色一情一乱一伦一区二区三区丨| www.久久爱.com| 久久综合丝袜日本网| 国产成人成网站在线播放青青| 国产精品玖玖玖在线资源| 日本亚洲欧洲色α| 亚洲精品国产成人影院| 亚洲japanese制服美女| 一区二区三区午夜视频| 岛国一区二区三区高清视频| 午夜亚洲性色福利视频| 超碰免费在线公开| 国产午夜精品理论片a级大结局 | 亚洲精品三级| 一本色道久久88亚洲精品综合| 欧美激情在线看| 91黄页在线观看| 日韩av片电影专区| 久久综合狠狠综合久久综合88| 欧美hdxxxxx| 国产精品久久久久影院色老大| 中文字幕久精品免| 成人视屏免费看| 一本久道中文无码字幕av| 久久超碰97中文字幕| 久久福利电影| 国产精品影视网| 欧美日韩精品免费观看| 黄色成人美女网站| 亚洲欧美国产日韩天堂区| 日本精品在线| 亚洲黄色片网站| a视频在线观看免费| 一区二区三区四区在线播放| 成人在线免费看片| 国产精品资源在线观看| 久久视频这里有精品| 亚洲视频在线观看三级| 国产www.大片在线| 亚洲片国产一区一级在线观看| 欧美一区自拍| 中文字幕一区二区三区四区五区六区 | 国产探花在线精品| 欧美大胆a视频| 黄色在线免费观看大全| 蜜桃av一区二区三区| 尤物免费看在线视频| 欧美日韩高清影院| 成人在线爆射| 好吊妞www.84com只有这里才有精品 | 日本999视频| 成人在线观看a| 亚洲福利视频导航| 77导航福利在线| 欧美老年两性高潮| 日韩精品黄色| 欧美一区二区性放荡片| 婷婷无套内射影院| 一区二区三区高清在线| 中文字幕日本一区| 99re在线国产| 国产欧美精品日韩区二区麻豆天美| 爆操欧美美女| 国产精品第一页在线| 欧美经典一区二区三区| 欧美亚洲福利| 香蕉521av成人网| 国产69精品久久久久9999apgf| 日本久久精品| 高清欧美精品xxxxx| 久久久久综合网| 欧美黄色a视频| 宅男av一区二区三区| 亚洲国产成人精品女人久久久| 欧美高清一区| 你懂的视频在线| 成人激情电影一区二区| 亚洲国产美女搞黄色| 另类ts人妖一区二区三区| 国产男女无遮挡| 97超级碰碰人国产在线观看| 亚洲国产一区二区在线播放| 欧美国产激情| 日韩精品亚洲人成在线观看| 好吊色欧美一区二区三区四区| 欧美日韩不卡视频| 国内成人自拍视频| 精品欧美午夜寂寞影院| 国产爆初菊在线观看免费视频网站| 视频二区一区| 精品国产一区二区三区日日嗨 | 午夜精品久久久99热福利| 精品国偷自产国产一区| 国产精品自在欧美一区| а√最新版地址在线天堂 | 91久久在线观看| 亚洲成人激情图| 欧美日韩国产中文精品字幕自在自线| 国产一区二区中文| 日本欧美一区| av在线免费观看网址| 久久天天躁狠狠躁夜夜爽蜜月| 91福利在线观看| 91精品综合久久久久久| 国产日韩欧美精品在线| 精品一区免费| 超碰在线公开| 三级短视频在线| 国产精品一区二区av| 中文字幕乱码亚洲精品一区| 国产精品99久久| 国产在线黄色| 免费99热在线观看| 国产黄色片免费在线观看| 精品久久精品久久| 97视频网站入口| 亚洲三级黄色在线观看| 欧美日韩在线一区二区| 北条麻妃国产九九精品视频| 亚洲综合国产| 日本麻豆一区二区三区视频| 亚洲精品精选| 亚洲视频精品| 欧美阿v一级看视频| 欧美顶级毛片在线播放| 久久不卡日韩美女| 黄色在线视频网站| 97视频在线观看网站| 在线看小视频| 在线国产1区| 成人性生交大片免费看午夜| 91免费在线| 96sao精品免费视频观看| 在线综合亚洲| 黄色污污视频在线观看| 中文字幕一区二区三区四区五区六区 | 日韩亚洲成人av在线| 国产性色av一区二区| 久久精品中文字幕电影| 久久国产一区二区三区| 欧美激情啊啊啊| 欧美一区二区三区免费视| 99c视频在线| www.日本一区| 日本电影一区二区在线观看| 中出福利视频| 色网在线视频| 国产三级在线播放| 97久久精品一区二区三区的观看方式| av自拍一区| 最新成人av网站| 成人美女在线观看| 亚洲欧美激情小说另类| 337p亚洲精品色噜噜噜| 亚洲欧美综合精品久久成人| 久久久久免费精品国产| 国产精品一区二区三区精品 | 最新日韩三级| 高清电影在线免费观看|