• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 重溫Python的XML工具

    發表于:2007-07-04來源:作者:點擊數: 標簽:
    David Mertz 創作的可愛的 Python 的第一、第二部分概述了在 Python 中使用 XML。然而,在那些最初的文章出現后,Python 中的 XML 工具有了很大的發展。不幸的是,這些改進中的大多數并不向后兼容。在這個特別部分中,重溫了作者先前對 XML 工具的討論,并提

    David Mertz 創作的可愛的 Python 的第一、第二部分概述了在 Python 中使用 XML。然而,在那些最初的文章出現后,Python 中的 XML 工具有了很大的發展。不幸的是,這些改進中的大多數并不向后兼容。在這個特別部分中,重溫了作者先前對 XML 工具的討論,并提供最新的代碼示例。

    在許多情況下,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 aclearcase/" target="_blank" >ccumulator
        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 輸出比僅將 <tag1>...</tag1> 寫入文件的方法更靈活。

     

    使用 xml.dom 模塊的語法與早期的文章相比有了一些變動。Python 2.0 中自帶的 DOM 實現被稱為 xml.dom.minidom,并提供輕量級和小型版本的 DOM。顯然,完整的 XML-SIG 的 DOM 中有些試驗性的特性并未被放入 xml.dom.minidom 中,但大家并不會注意到這一點。

    生成 DOM 對象很簡單;只需:

    清單 4: 在 XML 文件中創建 Python DOM 對象

    from xml.dom.minidom import parse, parseString
    dom1 = parse('mydata.xml') # parse an XML file by name

     

     

    使用 DOM 對象是種非常直接的 OOP 模式的工作。然而,經常在無法立刻簡單區分的層級(除了循環列舉)中碰到許多類似清單的屬性。例如,以下是一段普通的 DOM Python 代碼片斷:

    清單 5: 通過 Python DOM 節點對象的迭代

    for node in dom_node.childNodes:
        if node.nodeName == '#text':      # PCDATA is a kind of node,
            PCDATA = node.nodeValue       # but not a new subtag
        elif node.nodeName == 'spam':
            spam_node_list.append(node) # Create list of <spam> nodes

     

     

    Python 標準說明文檔中有一些更詳細的 DOM 示例。我的早期文章中有關使用 DOM 對象的示例(請參閱參考資料)指出的方向仍然是正確的,但是文章發布后至今,一些方法和屬性名稱以更改,因此請查閱一下 Python 的說明文檔。

    模塊: pyxie
    pyxie 模塊是在 Python 標準 XML 支持之上構建的,它為 XML 文檔提供了附加的高級接口。pyxie 將完成兩項基本操作:它將 XML 文檔轉換成一種更易于進行語法分析的基于行的格式;并且它提供了將 XML 文檔當作可操作樹處理的方法。pyxie 所使用的基于行的 PYX 格式是不受語言限制的,其工具適用于幾種語言??傊?,文檔的 PYX 表示與其 XML 表示相比,更易于使用常見的基于行的文本處理工具進行處理,如 grep、sed、awk、bash、perl,或標準 python 模塊,如 string 和 re。根據結果,從 XML 轉換到 PYX 可能節省許多工作。

    pyxie 將 XML 文檔當作樹處理的概念與 DOM 中的思路相似。由于 DOM 標準得到許多編程語言的廣泛支持,那么如果 XML 文檔的樹型表示是必需的,大多數程序員會使用 DOM 標準而非 pyxie。

    更多模塊:xml_pickle 和 xml_objectify
    我自行開發了處理 XML 的高級模塊,稱為 xml_pickle 和 xml_objectify。我還在其它地方寫過許多類似模塊(請參閱參考資料),在此不必做過多的介紹。當你“用 Python 思考”而不是“用 XML 思考”時,這些模塊非常有用。特別是 xml_objectify 自身對程序員隱藏了幾乎所有的 XML 線索,使您在程序中充分使用 Python “原始”對象。實際的 XML 數據格式幾乎被抽象得不可見。同樣,xml_pickle 使 Python 程序員以“原始” Python 對象開始,該對象的數據可以來源于任何源代碼,然后把它們(連續地)放入其他用戶以后可能需要的 XML 格式。

    參考資料

    如想獲得處理 XML 的 Python 2.0+ 模塊的詳細說明文檔,最佳起點是 Python 庫參考大全中的結構化標記處理工具部分。請搜索所有文件名以 xml 開頭的包。
    Python XML 專門興趣組是個提供討論的論壇,同時提供使用 Python 處理 XML 的工具實現。而且,Python Software Foundation 維護著一系列專門興趣組 (SIGs),目標為“集中合作力量開發、提高或維護專門 Python 資源”。
    在 Vaults of Parnassus XML 頁面上有一個出色的 Python 代碼和工具庫。
    請訪問 Pyxie 主頁,下載 Pyxie 和相關實用工具,并獲得關于 Pyxie 和 PYX 的常見問題答案。
    從 gnosis.cx/download/charming_python_1r.zip 獲得文中提及和使用的文件 (quotations.dtd, sample.xml, try_sax.py, try_sax.pyc, try_xmllib.py)。
    作者 David Mertz 文中提到的可愛的 Python 中兩部分原文在 將 XML 和 Python 結合起來 (2000 年 6 月)和 DOM 的動態性(2000 年 7 月)。請參閱作者的可愛的 Python 專欄中的其他文章:

    在 Python 下開發全文 indexer(2001 年 4 月)
    Python 中的函數型編程,第 1 部分(2001 年 3 月)第 2 部分(2001 年 4 月)
    獲得版本 2.0(2001 年 2 月)
    更新您的 Python 閱讀清單(2001 年 2 月)
    針對 .NET 的 JPython 和 Python 內部資源(2000 年 12 月)
    Python 中的 TK 編程(2000 年 12 月)
    直接快速的重新裝載(2000 年 11 月)
    Python 實施的內部資源(2000 年 10 月)
    詛咒編程(2000 年 9 月)
    Python 中的文本處理(2000 年 9 月)
    使用狀態機(2000 年 8 月)
    我的第一個基于 Web 的過濾代理服務器(2000 年 7 月)
    另見
    XML 問題 #1: 將 XML 文檔作為對象的“Python 化”處理 (2000 年 8 月)
    XML 問題 #2: 將 XML 文檔作為對象的“Python 化”處理 (II)(2000 年 8 月)


    有關作者
    David 認為愚蠢的結合是沒腦子的妖怪所為,并在其寫作中努力追求??赏ㄟ^ mertz@gnosis.cx與 David 聯系;他的精力完全投入在 http://gnosis.cx/publish/ 上。非常歡迎對過去的、這一篇或將來的專欄文章提出意見和建議。

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>