進(jìn)一步了解Python中的XML 工具
模塊:xmllib
xmllib 是一個(gè)非驗(yàn)證的低級(jí)語法分析器。應(yīng)用程序員使用的 xmllib 可以覆蓋 XMLParser 類,并提供處理文檔元素(如特定或類屬標(biāo)記,或字符實(shí)體)的方法。從 Python 1.5x 到 Python 2.0+ 以來, xmllib 的使用方法并沒變化;在絕大多數(shù)情況下更好的選擇是使用 SAX 技術(shù),它也是種面向流的技術(shù),對(duì)語言和開發(fā)者來說更為標(biāo)準(zhǔn)。
本文中的示例與原來專欄中的相同:包括一個(gè)叫做 quotations.dtd 的 DTD 以及這個(gè) DTD 的文檔 sample.xml (請(qǐng)參閱 參考資料,以獲取本文中提到的文件的檔案)。以下的代碼顯示了 sample.xml 中每段引言的前幾行,并生成了非常簡單的未知標(biāo)記和實(shí)體的 ASCII 指示符。經(jīng)過分析的文本作為連續(xù)流來處理,所使用的任何累加器都由程序員負(fù)責(zé)(如標(biāo)記中的字符串 (#PCDATA),或所遇到的標(biāo)記的列表或詞典)。
清單 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)\n' 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()
驗(yàn)證
您可能需要展望標(biāo)準(zhǔn) XML 支持的未來的原因是,在進(jìn)行語法分析的同時(shí)需要進(jìn)行驗(yàn)證。不幸的是,標(biāo)準(zhǔn) Python 2.0 XML 包并不包括驗(yàn)證型語法分析器。
xmlproc 是 python 原有的語法分析器,它執(zhí)行幾乎完整的驗(yàn)證。如果需要驗(yàn)證型語法分析器, xmlproc 是 Python 當(dāng)前唯一的選擇。而且, xmlproc 提供其它語法分析器所不具備的各種高級(jí)和測試接口。
選擇一種語法分析器
如果決定使用 XML 的簡單 API (SAX) -- 它應(yīng)該用于復(fù)雜的事物,因?yàn)槠渌蟛糠止ぞ叨际窃谒幕A(chǔ)上建立的 -- 將為您完成許多語法分析器的分類工作。 xml.sax 模塊包含一個(gè)自動(dòng)選擇“最佳”語法分析器的設(shè)施。在標(biāo)準(zhǔn) Python 2.0 安裝中,唯一能選擇的語法分析器是 expat ,它是種 C 語言編寫的快速擴(kuò)展。然而,也可以在 $PYTHONLIB/xml/parsers 下安裝另一個(gè)語法分析器,以備選擇。設(shè)置語法分析器很簡單:
清單 2: Python 選擇最佳語法分析器的語句
import xml.sax parser = xml.sax.make_parser()
您還可以通過傳遞參數(shù)來選擇特定的語法分析器;但考慮到可移植性 -- 也為了對(duì)今后更好的語法分析器的向上兼容性 -- 最佳方法是使用 make_parser() 來完成工作。
您可以直接導(dǎo)入 xml.parsers.expat 。如果這樣做,您就能獲得 SAX 界面并不提供的一些特殊技巧。這樣, xml.parsers.expat 與 SAX 相比有些“低級(jí)”。但 SAX 技術(shù)非常標(biāo)準(zhǔn),對(duì)面向流的處理也非常好;大多數(shù)情況下 SAX 的級(jí)別正合適。通常情況下,由于 make_parser() 函數(shù)已經(jīng)能獲得 expat 提供的性能,因此純速度的差異很小。
什么是 SAX
考慮到背景因素,回答什么是 SAX 的較好答案是:
SAX (XML 的簡單 API)是 XML 語法分析器的公用語法分析器接口。它允許應(yīng)用程序作者編寫使用 XML 語法分析器的應(yīng)用程序,但是它卻獨(dú)立于所使用的語法分析器。(將它看作 XML 的 JDBC。)(Lars Marius Garshol,SAX for Python)
SAX -- 如同它提供的語法分析器模塊的 API -- 基本上是一個(gè) XML 文檔的順序處理器。使用它的方法與 xmllib 示例極其相似,但更加抽象。應(yīng)用程序員將定義一個(gè) handler 類,而不是語法分析器類,該 handler 類能注冊到任何所使用的語法分析器中。必須定義 4 個(gè) SAX 接口(每個(gè)接口都有幾個(gè)方法):DocumentHandler、DTDHandler、EntityResolver 和 ErrorHandler。創(chuàng)建語法分析器除非被覆蓋,否則它還連接默認(rèn)接口。這些代碼執(zhí)行與 xmllib 示例相同的任務(wù):
清單 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)\n' 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() 方法處理整個(gè)流或字符串,所以不必為語法分析器創(chuàng)建循環(huán); .parse() 同樣能靈活地接收一個(gè)文件名、一個(gè)文件對(duì)象,或是眾多的類文件對(duì)象(一些具有 .read() 方式)。
包:DOM
DOM 是一種 XML 文檔的高級(jí)樹型表示。該模型并非只針對(duì) Python,而是一種普通 XML 模型(請(qǐng)參閱 參考資料以獲取進(jìn)一步信息)。Python 的 DOM 包是基于 SAX 構(gòu)建的,并且包括在 Python 2.0 的標(biāo)準(zhǔn) XML 支持里。由于篇幅所限,沒有將代碼示例加到本文中,但在 XML-SIG 的 "Python/XML HOWTO" 中給出了一個(gè)極好的總體描述:
文檔對(duì)象模型為 XML 文檔指定了樹型表示。頂級(jí)文檔實(shí)例是樹的根,它只有一個(gè)子代,即頂級(jí)元素實(shí)例;這個(gè)元素有表示內(nèi)容和子元素的子節(jié)點(diǎn),他們也可以有子代,以此類推。定義的函數(shù)允許隨意遍歷結(jié)果樹,訪問元素和屬性值,插入和刪除節(jié)點(diǎn),以及將樹轉(zhuǎn)換回 XML。
DOM 可以用于修改 XML 文檔,因?yàn)榭梢詣?chuàng)建一棵 DOM 樹,通過添加新節(jié)點(diǎn)和來回移動(dòng)子樹來修改這棵樹,然后生成一個(gè)新的 XML 文檔作為輸出。您也可以自己構(gòu)造一棵 DOM 樹,然后將它轉(zhuǎn)換成 XML;用這種方法生成 XML 輸出比僅將 <tag1>...</tag1> 寫入文件的方法更靈活。
使用 xml.dom 模塊的語法與早期的文章相比有了一些變動(dòng)。Python 2.0 中自帶的 DOM 實(shí)現(xiàn)被稱為 xml.dom.minidom ,并提供輕量級(jí)和小型版本的 DOM。顯然,完整的 XML-SIG 的 DOM 中有些試驗(yàn)性的特性并未被放入 xml.dom.minidom 中,但大家并不會(huì)注意到這一點(diǎn)。
生成 DOM 對(duì)象很簡單;只需:
清單 4: 在 XML 文件中創(chuàng)建 Python DOM 對(duì)象
from xml.dom.minidom import parse, parseString dom1 = parse('mydata.xml') # parse an XML file by name
使用 DOM 對(duì)象是種非常直接的 OOP 模式的工作。然而,經(jīng)常在無法立刻簡單區(qū)分的層級(jí)(除了循環(huán)列舉)中碰到許多類似清單的屬性。例如,以下是一段普通的 DOM Python 代碼片斷:
清單 5: 通過 Python DOM 節(jié)點(diǎn)對(duì)象的迭代
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 標(biāo)準(zhǔn)說明文檔中有一些更詳細(xì)的 DOM 示例。我的早期文章中有關(guān)使用 DOM 對(duì)象的示例(請(qǐng)參閱 參考資料)指出的方向仍然是正確的,但是文章發(fā)布后至今,一些方法和屬性名稱以更改,因此請(qǐng)查閱一下 Python 的說明文檔。
模塊: pyxie
pyxie 模塊是在 Python 標(biāo)準(zhǔn) XML 支持之上構(gòu)建的,它為 XML 文檔提供了附加的高級(jí)接口。 pyxie 將完成兩項(xiàng)基本操作:它將 XML 文檔轉(zhuǎn)換成一種更易于進(jìn)行語法分析的基于行的格式;并且它提供了將 XML 文檔當(dāng)作可操作樹處理的方法。 pyxie 所使用的基于行的 PYX 格式是不受語言限制的,其工具適用于幾種語言??傊臋n的 PYX 表示與其 XML 表示相比,更易于使用常見的基于行的文本處理工具進(jìn)行處理,如 grep、sed、awk、bash、perl,或標(biāo)準(zhǔn) python 模塊,如 string 和 re 。根據(jù)結(jié)果,從 XML 轉(zhuǎn)換到 PYX 可能節(jié)省許多工作。
pyxie 將 XML 文檔當(dāng)作樹處理的概念與 DOM 中的思路相似。由于 DOM 標(biāo)準(zhǔn)得到許多編程語言的廣泛支持,那么如果 XML 文檔的樹型表示是必需的,大多數(shù)程序員會(huì)使用 DOM 標(biāo)準(zhǔn)而非 pyxie 。
更多模塊: xml_pickle 和 xml_objectify
我自行開發(fā)了處理 XML 的高級(jí)模塊,稱為 xml_pickle 和 xml_objectify 。我還在其它地方寫過許多類似模塊(請(qǐng)參閱 參考資料),在此不必做過多的介紹。當(dāng)你“用 Python 思考”而不是“用 XML 思考”時(shí),這些模塊非常有用。特別是 xml_objectify 自身對(duì)程序員隱藏了幾乎所有的 XML 線索,使您在程序中充分使用 Python “原始”對(duì)象。實(shí)際的 XML 數(shù)據(jù)格式幾乎被抽象得不可見。同樣, xml_pickle 使 Python 程序員以“原始” Python 對(duì)象開始,該對(duì)象的數(shù)據(jù)可以來源于任何源代碼,然后把它們(連續(xù)地)放入其他用戶以后可能需要的 XML 格式。
相關(guān)文章
Python利用Pillow(PIL)庫實(shí)現(xiàn)驗(yàn)證碼圖片的全過程
這篇文章主要給大家介紹了關(guān)于Python利用Pillow(PIL)庫實(shí)現(xiàn)驗(yàn)證碼圖片的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10詳解pycharm連接遠(yuǎn)程linux服務(wù)器的虛擬環(huán)境的方法
這篇文章主要介紹了pycharm連接遠(yuǎn)程linux服務(wù)器的虛擬環(huán)境的詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11Python從MySQL數(shù)據(jù)庫中面抽取試題,生成試卷
這篇文章主要介紹了Python如何從MySQL數(shù)據(jù)庫中面抽取試題,生成試卷,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-01-01OpenCV 使用imread()函數(shù)讀取圖片的六種正確姿勢
這篇文章主要介紹了OpenCV 使用imread()函數(shù)讀取圖片的六種正確姿勢,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07python 使用raw socket進(jìn)行TCP SYN掃描實(shí)例
這篇文章主要介紹了python 使用raw socket進(jìn)行TCP SYN掃描實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-05-05python3 常見解密加密算法實(shí)例分析【base64、MD5等】
這篇文章主要介紹了python3 常見解密加密算法,結(jié)合實(shí)例形式分析了Python的base64模塊加密,以及基于pycrypto模塊的MD5加密等相關(guān)操作技巧,需要的朋友可以參考下2019-12-12mac使用python識(shí)別圖形驗(yàn)證碼功能
這篇文章主要介紹了mac使用python識(shí)別圖形驗(yàn)證碼功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01