發(fā)布日期: 2006-10-17 | 更新日期: 2006-10-17
Chris Lovett
Microsoft
摘要:本文介紹新版本的 XML Notepad。該工具于 1998 年首次推出,但多年來始終一成不變。這一版本利用了 System.Xml 的優(yōu)勢并增加了一些新功能。
本頁內(nèi)容
我終于抽出時間來履行我在 MSDN 對一個朋友所做的承諾?;厮莸?1998 年,我們發(fā)布了 Murray Low 用 C++ 編寫的 XML Notepad。后來,由于它在支持 XML 標準方面表現(xiàn)落后,而我們又沒有時間加以解決,因而被 MSDN 所拋棄。但事實證明 Murray 所做的這項工作是出色的,要求恢復(fù) XML Notepad 的請求如潮水般涌向 MSDN,因此 MSDN 責(zé)成我來完成這個工具的更新?lián)Q代。
我從 1999 年以來一直在用 C# 編寫 System.Xml,因此我相信我能通過 .NET Framework 相當(dāng)迅速地完成更新?lián)Q代。然而問題是,它只是我日常工作中眾多編外項目之一,一切可想而知!好在我的一個好朋友 Michael Corning 對此很感興趣,他幫助我渡過難關(guān),還親自增加了一些很棒的功能。Dan Doris 也予我以同情,幫忙發(fā)現(xiàn)了一些嚴重的錯誤。就這樣,我們終于為想要快速查看和編輯 XML 文檔的人呈現(xiàn)了一些有用的東西。
對于那些了解這個工具初始版本的人而言,這個界面看起來應(yīng)該很熟悉:左邊的樹視圖與右邊的節(jié)點文本視圖同步,手動微調(diào)工具欄按鈕可以在節(jié)點樹中快速上下移動各節(jié)點(參見圖 1)。由于距第一版的時間太過久遠,我不得不利用了 System.Xml 中的一些強大內(nèi)容并增加了一些原來版本所沒有的點綴性功能:
•
在樹視圖和文本視圖中可以增量搜索 (CTRL+I),這樣視圖會隨著搜索內(nèi)容的輸入而導(dǎo)航到最匹配的節(jié)點。
•
剪切/復(fù)制/粘貼功能支持簡單、可交互 XML 格式的完整命名空間。
•
支持拖放功能,從而可以輕松操控樹視圖,甚至能跨越 XML Notepad 的不同實例或者從文件系統(tǒng)進行操控。
•
對所有編輯操作可以進行無限次撤消/重做。
•
對大型文本節(jié)點值進行在位編輯、彈出編輯和多行編輯,IntelliSense 以期望的元素和屬性為基礎(chǔ)。
•
可通過選項對話框配置字體和顏色。
•
完整查找/替換對話框支持 regex 和 XPath 表達式。
•
在處理大型 XML 文檔方面性能良好(在約一秒鐘內(nèi)能加載一篇 3MB 的文檔)。
•
在編輯的同時進行即時 XML 架構(gòu)驗證,錯誤和警告消息顯示在任務(wù)列表窗口中。
•
支持針對日期、日期時間、時間和顏色數(shù)據(jù)類型的自定義編輯器。
•
提供顯示 XSLT 轉(zhuǎn)換結(jié)果的 HTML 查看器。
•
內(nèi)置有 XML Diff 工具。
設(shè)計與實現(xiàn)
在
可下載程序包中,提供了核心 XmlNotepad dll 項目、用于構(gòu)建 XmlNotepad.exe 的 Application 項目、用于 XML diff 功能的 XmlDiff 庫項目、用于構(gòu)建 .msi 安裝程序的 Setup 項目、用于測試 XML Notepad 的 UnitTest 項目和用于使用 HTML Help Workshop 工具構(gòu)建 Help.chm 文件的 Help 項目。
圖 1. XML Notepad 界面
下圖顯示各主要 UI 類之間的關(guān)系。主窗體中包含所有的 UI 元素(從 TaskList 到主 XmlTreeView 以及兩者之間的 Resizer);它是 FormSearch、FormSchemas、FormOption 和 FormAbout 等多個對話框的啟動點。
圖 2. 主要 UI 類
主要選項卡控件包括 XmlTreeView 和顯示 XSL 輸出的 XsltViewer。XmlTreeView 包含左側(cè)的 TreeView 和右側(cè)的 NodeTextView,并能協(xié)調(diào)兩個視圖間的滾動。TreeView 和 NodeTextView 都使用 TextEditorOverlay 組件提供相同的 IntelliSense 編輯功能。XmlTreeView 實現(xiàn)了 IFindTarget,“查找”對話框 (FormSearch) 用它來實現(xiàn)查找/替換功能。
圖 3.“查找”對話框
“查找”對話框支持全文本、regex 或 XPath 表達式查找,并能按名稱或值進行篩選。這里顯示的是 XPath 搜索,它還提供了一個表格,用于輸入查詢中所使用的命名空間前綴映射。
返回頁首驗證、IntelliSense 與自定義編輯器
IntelliSense 是新增的最強大功能,它由通過 SchemaCache 提供的 XML 架構(gòu)信息驅(qū)動。例如,如果您的元素或?qū)傩杂梢粋€ XSD simpleType 定義,此 simpleType 又包含枚舉約束面的列表,那么您將獲得如下的一個下拉列表:
圖 4. 下拉列表值
其工作方式是這樣的:檢查器會跟蹤每個編輯操作,以在 TaskList 中檢查文檔和報表錯誤。這一過程也會將每個元素和屬性的 System.Xml.Schema.XmlSchemaType 信息放入 XmlDocument 中;然后,在編輯該節(jié)點的值時,TextEditorOverlay 會使用 XmlIntelliSenseProvider 返回可能值列表。在上面的例子中,它返回了來自 simpleType 枚舉約束面的值。對于樹視圖中的元素名 IntelliSense,XmlIntelliSenseProvider 再次調(diào)用檢查器,在 System.Xml.Schema.XmlSchemaValidator 上捕獲 GetExpectedParticles 和 GetExpectedAttributes 并用其來提供 IntelliSense。
圖 5. 樹視圖中的 IntelliSense
TextEditorOverlay 還支持 DateTimeEditor、UriBuilder 或 ColorBuilder 等自定義編輯器。自定義編輯器分為兩種類型:IXmlEditors 和 IXmlBuidlers。前者是取代默認文本框的內(nèi)嵌式編輯器,后者是彈出式對話框(如 OpenFileDialog 或 ColorDialog)。編輯器類型是從架構(gòu)類型信息派生而來的,其中“xs:date”、“xs:time”和“xs:datetime”產(chǎn)生 DateTimeEditor,“xs:anyURI”產(chǎn)生 UriBuilder。您也可以使用“http://schemas.microsoft.com/Visual-Studio-IntelliSense”命名空間中的自定義“vs:builder”屬性注釋此架構(gòu)。有關(guān)詳細信息,請參見幫助內(nèi)容。
返回頁首無限次撤消/重做
為了實現(xiàn)撤消/重做,我對 Undo 和 Redo 方法采用了常見的命令對象設(shè)計模式。UndoManager 負責(zé)將這些對象收集在一個列表中。而 UndoManager 的狀態(tài)控制“撤消”/“重做”菜單項的啟用/禁用狀態(tài)。當(dāng)用戶選擇“撤消”菜單項時,會以活動命令調(diào)用 Undo 方法,并將該命令壓入 Redo 堆棧。
圖 6. 樹視圖中的“撤消/重做”
編輯器中的某些操作引發(fā)了樹中的許多編輯操作,包括全部替換操作和命名空間屬性值編輯操作。(更改命名空間屬性值時,綁定到該命名空間的每個 XmlNode 都需要以一個新的命名空間 URI 重新構(gòu)建,這顯然會影響到樹中的許多節(jié)點!)因此,為了將這些操作融入一個基本的重做操作,利用了一個包含更小編輯命令列表的 CompoundCommand 對象,此 CompoundCommand 被放入 UndoManager 中。
其他更簡單的命令對象包括以下項目,它們?nèi)繉?XmlTreeNode 和 XmlNode 對象進行操作:
圖 7. 樹視圖中的命令對象
PasteCommand 是一個特殊命令,因為它將隨機 XML 文本從剪貼板取下,并在樹中當(dāng)前所選元素的環(huán)境中進行解析,從而繼承了作用域中的命名空間。助手類 TreeData 使用以 XmlParserContext 作為輸入的特殊 XmlTextReader 構(gòu)造函數(shù)。
返回頁首單元測試
我必須將測試新 XML Notepad 的工作做好,我說服自己使用了新的 Visual Studio 2005
UnitTest 項目。UnitTest 可以從 Visual Studio 中新“測試”菜單下的 TestManager 運行,它可以啟動 XML Notepad 并執(zhí)行我所編寫的 15 個測試方法。
圖 8. UnitTest
測試完畢時,可以在“測試結(jié)果”窗口單擊右鍵并選擇“代碼覆蓋率結(jié)果”。這樣,程序會匯總出每個功能所覆蓋的塊數(shù)。雙擊列表中的行可以顯示一個彩色編碼的源代碼視圖,用以準確顯示所覆蓋的代碼。這種方式使我真正輕松地獲得了高達 85% 的代碼覆蓋率。
唯一需要注意的是,當(dāng)您在調(diào)試程序下運行這些測試時不會獲得代碼覆蓋率,UnitTest 項目會在解決方案旁創(chuàng)建一個稱為“localtestrun.testrunconfig”或“XmlNotepad.vsmdi”的文件,這個文件不能丟失。否則,就將無法獲得代碼覆蓋率。除此之外,我不得不說這個新的 UnitTest 是 Visual Studio 2005 中最棒的新功能之一。