python與XML的結合實踐教程

來源:互聯網
上載者:User
這次給大家帶來python與XML的結合實踐教程,python與XML結合實踐的注意事項有哪些,下面就是實戰案例,一起來看一下。

這個項目的名稱與其叫做萬能的XML不如叫做自動構建網站,根據一份XML檔案,產生對應目錄結構的網站,不過只有html還是太過於簡單了,如果要是可以連帶產生css那就比較強大了。這個有待後續研發,先來研究下怎麼html網站結構。 既然是通過XML結構產生網站,那所有的事情都應該由這個XML檔案來。先來看下這個XML檔案,website.xml:

<website> <page name="index" title="Home page"> <h1>Welcome to my Home page</h1> <p>Hi, there. My name is Mr.gumby,and this is my home page,here are some of my int:</p> <ul>  <li><a href="interests/shouting.html" rel="external nofollow" >Shouting</a></li>  <li><a href="interests/sleeping.html" rel="external nofollow" >Sleeping</a></li>  <li><a href="interests/eating.html" rel="external nofollow" >Eating</a></li> </ul> </page> <directory name="interests">  <page name="shouting" title="Shouting">   <h1>shouting page</h1>   <p>....</p>  </page>  <page name="sleeping" title="Sleeping">   <h1>sleeping page</h1>   <p>...</p>  </page>  <page name="eating" title="Eating">    <h1>Eating page</h1>    <p>....</p>  </page> </directory></website>

有了這個檔案,下面應該來看怎麼通過這個檔案產生網站。

首先我們要解析這個xml檔案,python解析xml和在java中一樣,有兩種方式,SAX和DOM,兩種處理方式不同點在於速度和範圍,前者講究的是效率,每次只處理文檔的一小部分,快速而能有效利用記憶體,後者是相反的處理方式,先把所有的文檔載入到記憶體,然後再進行處理,速度比較慢,也比較消耗記憶體,唯一的好處就是可以操作整個文檔。

在python中使用sax方式處理xml要先引入xml.sax中的parse函數,還有xml.sax.handler中的ContentHandler,後面的這個類是要和parse函數來配合使用的。使用方式如下: parse('xxx.xml',xxxHandler),這裡面的xxxHandler要繼承上面的ContentHandler,不過只要繼承就行,不需要有所作為。 然後這個parse函數在處理xml檔案的時候,會調用xxxHandler中的startElement函數和endElement函數來一個xml中的標籤的開始和結束,中間的過程使用一個名為characters的函數來處理標籤內部的所有字串。

有了上面的這些認識,我們已經知道如何處理xml檔案了,然後再來看那個罪惡的源頭website.xml檔案,分析其結構,只有兩個節點:page和directory,很明顯page表示一個頁面,directory表示一個目錄。

所以處理這個xml檔案的思路就變的清晰了。讀取xml檔案的每一個節點,然後判斷是page還是directory如果是page則建立html頁面,然後把節點中的內容寫到檔案裡。如果遇到directory就建立一個檔案夾,然後再處理其內部的page節點(如果存在的話)。
下面來看這部分代碼,書中的實現比較複雜,比較靈活。先來看,然後在分析。

from xml.sax.handler import ContentHandlerfrom xml.sax import parseimport osclass Dispatcher:    def dispatch(self, prefix, name, attrs=None):        mname = prefix + name.capitalize()        dname = 'default' + prefix.capitalize()        method = getattr(self, mname, None)        if callable(method): args = ()        else:            method = getattr(self, dname, None)            args = name,        if prefix == 'start': args += attrs,        if callable(method): method(*args)    def startElement(self, name, attrs):        self.dispatch('start', name, attrs)    def endElement(self, name):        self.dispatch('end', name)class WebsiteConstructor(Dispatcher, ContentHandler):    passthrough = False    def init(self, directory):        self.directory = [directory]        self.ensureDirectory()    def ensureDirectory(self):        path = os.path.join(*self.directory)        print path        print '----'        if not os.path.isdir(path): os.makedirs(path)    def characters(self, chars):        if self.passthrough: self.out.write(chars)    def defaultStart(self, name, attrs):        if self.passthrough:            self.out.write('<' + name)            for key, val in attrs.items():                self.out.write(' %s="%s"' %(key, val))            self.out.write('>')    def defaultEnd(self, name):        if self.passthrough:            self.out.write('</%s>' % name)    def startDirectory(self, attrs):        self.directory.append(attrs['name'])        self.ensureDirectory()    def endDirectory(self):        print 'endDirectory'        self.directory.pop()    def startPage(self, attrs):        print 'startPage'        filename = os.path.join(*self.directory + [attrs['name']+'.html'])        self.out = open(filename, 'w')        self.writeHeader(attrs['title'])        self.passthrough = True    def endPage(self):        print 'endPage'        self.passthrough = False        self.writeFooter()        self.out.close()    def writeHeader(self, title):        self.out.write('<html>\n <head>\n  <title>')        self.out.write(title)        self.out.write('</title>\n </head>\n <body>\n')    def writeFooter(self):        self.out.write('\n </body>\n</html>\n')parse('website.xml',WebsiteConstructor('public_html'))

看起來這個程式上面分析的複雜了一些,不過偉人毛毛說過,任何複雜的程式都是紙老虎。那我們再來分析一下這個程式。

首先看到這個程式是有兩個類,其實完全可以當作一個類,因為有了繼承。

然後再來看它多了些什麼,除了我們分析出來的startElement和endElement以及characters,多出來了startPage,endPage;startDirectory,endDirectory;defaultStart,defaultEnd;ensureDirectory;writeHeader,writeFooter;和dispatch,這些個函數。除了dispatch,前面的函數都很好理解,每一對函數都是單純的處理對應的html標籤以及xml節點。而dispatch比較複雜,複雜之處在於他是用來動態拼合函數並且進行執行的。

dispatch的處理思路是,首先根據傳遞的參數(就是操作名稱以及節點名稱)判斷是否存在對應的函數如startPage,如果不存在則執行default+操作名稱:如defaultStart。

一個函數一個函數搞清楚之後,就知道整個處理流程是什麼樣了。首先建立一個public_html的檔案,存放整個網站,然後讀xml的節點,通過startElement和endElement調用dispatch進行處理。然後就是dispatch怎麼調用具體的處理函數了。 到此為止,這個項目算是分析完了。

主要掌握的內容一個是python中使用SAX處理XML,另一個就是python中的函數的使用,比如getattr,傳參數時的星號……

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

Python怎麼把資料框內資料寫入資料庫

在Python複製中對象生命週期如何使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.