歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> 更多Linux

XML文檔的理想語言分析Python的特點

  在許多情況下,Python 是使用 XML 文檔的理想語言。像 Perl、REBOL、REXX 和 TCL 一樣,它是一種靈活的腳本語言,並且有強大的文本操作能力。而且,除了對多數類型的文本文件(或流文件)編碼外,XML 文檔還編碼大量復雜的數據結構。    繼續在 Python 2.0 中對 XML 的支持  文本處理中常見的“讀取幾行,並將它們與一些規則表達式比較”樣式通常不能很好地適合對 XML 進行徹底語法分析和處理。幸好,Python(與大多數其它語言相比)不僅有處理復雜數據結構的直接方法(通常使用類和屬性),還有一系列 XML 相關的模塊可以幫助語法分析、處理和生成 XML。    XML-SIG (專門興趣組)的成員為維護 Python 一系列 XML 工具做了許多工作。與其它 Python 專門興趣組一樣,XML-SIG 要維護郵件發送列表、列表檔案、有用的參考大全、文檔、標准包和其它資源(請參閱本文後的參考資料)。    從 Python 2.0 開始,Python 在其標准發行版中包括大多數 XML-SIG 項目。最新的 XML-SIG 包可能包含一些 Python 標准發行版中沒有的“極端先進”特性,但出於面向絕大多數人的目的 -- 包括本文中的討論 -- Python 2.0 的 XML 支持將是您感興趣的。幸運的是,早期 Python 版本對 xmllib 的基本支持在 Python 2.0+ 下有了很大進步。目前,Python 用戶能正常的選擇 DOM、SAX 和 eXPat 技術來處理 XML (使用其他編程語言的 XML 開發人員將會意識到這些)。    模塊:xmllib  xmllib 是一個非驗證的低級語法分析器。應用程序員使用的 xmllib 可以覆蓋 XMLParser 類,並提供處理文檔元素(如特定或類屬標記,或字符實體)的方法。從 Python 1.5x 到 Python 2.0+ 以來,xmllib 的使用方法並沒變化;在絕大多數情況下更好的選擇是使用 SAX 技術,它也是種面向流的技術,對語言和開發者來說更為標准。    本文中的示例與原來專欄中的相同:包括一個叫做 quotations.dtd 的 DTD 以及這個 DTD 的文檔 sample.xml (請參閱參考資料,以獲取本文中提到的文件的檔案)。以下的代碼顯示了 sample.xml 中每段引言的前幾行,並生成了非常簡單的未知標記和實體的 ASCII 指示符。經過分析的文本作為連續流來處理,所使用的任何累加器都由程序員負責(如標記中的字符串 (#PCDATA),或所遇到的標記的列表或詞典)。    清單 1: try_xmllib.py    import xmllib, string    classQuotationParser(xmllib.XMLParser):    """Crude xmllib extractor for quotations.dtd document"""    def__init__(self):      xmllib.XMLParser.__init__(self)      self.thisquote = ''       # quotation accumulator    defhandle_data(self, data):      self.thisquote = self.thisquote + data    defsyntax_error(self, message):      pass    defstart_quotations(self, attrs): # top level tag      print '--- Begin Document ---'    defstart_quotation(self, attrs):      print 'QUOTATION:'    defend_quotation(self):      print string.join(string.split(self.thisquote[:230]))+'...',      print '('+str(len(self.thisquote))+' bytes)'      self.thisquote = ''    defunknown_starttag(self, tag, attrs):      self.thisquote = self.thisquote + '{'    defunknown_endtag(self, tag):      self.thisquote = self.thisquote + '}'    defunknown_charref(self, ref):      self.thisquote = self.thisquote + '?'    defunknown_entityref(self, ref):      self.thisquote = self.thisquote + '#'    if __name__ == '__main__':    parser = QuotationParser()    for c in open("sample.xml").read():      parser.feed(c)    parser.close()    驗證  您可能需要展望標准 XML 支持的未來的原因是,在進行語法分析的同時需要進行驗證。不幸的是,標准 Python 2.0 XML 包並不包括驗證型語法分析器。    xmlproc 是 python 原有的語法分析器,它執行幾乎完整的驗證。如果需要驗證型語法分析器, xmlproc 是 Python 當前唯一的選擇。而且,xmlproc 提供其它語法分析器所不具備的各種高級和測試接口。    選擇一種語法分析器  如果決定使用 XML 的簡單 API (SAX) -- 它應該用於復雜的事物,因為其它大部分工具都是在它的基礎上建立的 -- 將為您完成許多語法分析器的分類工作。xml.sax 模塊包含一個自動選擇“最佳”語法分析器的設施。在標准 Python 2.0 安裝中,唯一能選擇的語法分析器是 expat,它是種 C 語言編寫的快速擴展。然而,也可以在 $PYTHONLIB/xml/parsers 下安裝另一個語法分析器,以備選擇。設置語法分析器很簡單:    清單 2: Python 選擇最佳語法分析器的語句    import xml.sax  parser = xml.sax.make_parser()    您還可以通過傳遞參數來選擇特定的語法分析器;但考慮到可移植性 -- 也為了對今後更好的語法分析器的向上兼容性 -- 最佳方法是使用 make_parser() 來完成工作。    您可以直接導入 xml.parsers.expat。如果這樣做,您就能獲得 SAX 界面並不提供的一些特殊技巧。這樣,xml.parsers.expat 與 SAX 相比有些“低級”。但 SAX 技術非常標准,對面向流的處理也非常好;大多數情況下 SAX 的級別正合適。通常情況下,由於 make_parser() 函數已經能獲得 expat 提供的性能,因此純速度的差異很小。    什麼是 SAX  考慮到背景因素,回答什麼是 SAX 的較好答案是:    SAX (XML 的簡單 API)是 XML 語法分析器的公用語法分析器接口。它允許應用程序作者編寫使用 XML 語法分析器的應用程序,但是它卻獨立於所使用的語法分析器。(將它看作 XML 的 JDBC。)(Lars Marius Garshol,SAX for Python)  SAX -- 如同它提供的語法分析器模塊的 API -- 基本上是一個 XML 文檔的順序處理器。使用它的方法與 xmllib 示例極其相似,但更加抽象。應用程序員將定義一個 handler 類,而不是語法分析器類,該 handler 類能注冊到任何所使用的語法分析器中。必須定義 4 個 SAX 接口(每個接口都有幾個方法):DocumentHandler、DTDHandler、EntityResolver 和 ErrorHandler。創建語法分析器除非被覆蓋,否則它還連接默認接口。這些代碼執行與 xmllib 示例相同的任務:    清單 3: try_sax.py    "Simple SAX example, updated for Python 2.0+"  import string  import xml.sax  from xml.sax.handler import *    classQuotationHandler(ContentHandler):    """Crude extractor for quotations.dtd compliant XML document"""    def__init__(self):      self.in_quote = 0      self.thisquote = ''    defstartDocument(self):      print '--- Begin Document ---'    defstartElement(self, name, attrs):      if name == 'quotation':        print 'QUOTATION:'        self.in_quote = 1      else:        self.thisquote = self.thisquote + '{'    defendElement(self, name):      if name == 'quotation':        print string.join(string.split(self.thisquote[:230]))+'...',        print '('+str(len(self.thisquote))+' bytes)'        self.thisquote = ''        self.in_quote = 0      else:        self.thisquote = self.thisquote + '}'    defcharacters(self, ch):      if self.in_quote:        self.thisquote = self.thisquote + ch    if __name__ == '__main__':    parser = xml.sax.make_parser()    handler = QuotationHandler()    parser.setContentHandler(handler)    parser.parse("sample.xml")    與 xmllib 相比,上述示例中要注意兩件小事:.parse() 方法處理整個流或字符串,所以不必為語法分析器創建循環;.parse() 同樣能靈活地接收一個文件名、一個文件對象,或是眾多的類文件對象(一些具有 .read() 方式)。    包:DOM  DOM 是一種 XML 文檔的高級樹型表示。該模型並非只針對 Python,而是一種普通 XML 模型(請參閱參考資料以獲取進一步信息)。Python 的 DOM 包是基於 SAX 構建的,並且包括在 Python 2.0 的標准 XML 支持裡。由於篇幅所限,沒有將代碼示例加到本文中,但在 XML-SIG 的 "Python/XML HOWTO" 中給出了一個極好的總體描述:    文檔對象模型為 XML 文檔指定了樹型表示。頂級文檔實例是樹的根,它只有一個子代,即頂級元素實例;這個元素有表示內容和子元素的子節點,他們也可以有子代,以此類推。定義的函數允許隨意遍歷結果樹,訪問元素和屬性值,插入和刪除節點,以及將樹轉換回 XML。    DOM 可以用於修改 XML 文檔,因為可以創建一棵 DOM 樹,通過添加新節點和來回移動子樹來修改這棵樹,然後生成一個新的 XML 文檔作為輸出。您也可以自己構造一棵 DOM 樹,然後將它轉換成 XML;用這種方法生成 XML 輸出比僅將 <




Copyright © Linux教程網 All Rights Reserved