快乐12开奖走势图辽宁:the5fire的技术博客

彩票开奖查询 www.8a72.cn 关注Python、Django、Vim、Linux、Web开发、团队管理和互联网--Life is short, we need Python.


python项目练习三:万能的XML

作者:the5fire | 标签:   | 发布:2011-12-20 11:18 p.m. | 阅读量: 35663, 34887

这个项目的名称与其叫做万能的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">Shouting</a></li>
    <li><a href="interests/sleeping.html">Sleeping</a></li>
    <li><a href="interests/eating.html">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节点(如果存在的话)。

下面来看这部分代码,书中的实现比较复杂,比较灵活。先来看,然后在分析。

fromxml.sax.handlerimportContentHandlerfromxml.saximportparseimportosclassDispatcher:defdispatch(self,prefix,name,attrs=None):mname=prefix+name.capitalize()dname='default'+prefix.capitalize()method=getattr(self,mname,None)ifcallable(method):args=()else:method=getattr(self,dname,None)args=name,ifprefix=='start':args+=attrs,ifcallable(method):method(*args)defstartElement(self,name,attrs):self.dispatch('start',name,attrs)defendElement(self,name):self.dispatch('end',name)classWebsiteConstructor(Dispatcher,ContentHandler):passthrough=Falsedef__init__(self,directory):self.directory=[directory]self.ensureDirectory()defensureDirectory(self):path=os.path.join(*self.directory)printpathprint'----'ifnotos.path.isdir(path):os.makedirs(path)defcharacters(self,chars):ifself.passthrough:self.out.write(chars)defdefaultStart(self,name,attrs):ifself.passthrough:self.out.write('<'+name)forkey,valinattrs.items():self.out.write(' %s="%s"'%(key,val))self.out.write('>')defdefaultEnd(self,name):ifself.passthrough:self.out.write('</%s>'%name)defstartDirectory(self,attrs):self.directory.append(attrs['name'])self.ensureDirectory()defendDirectory(self):print'endDirectory'self.directory.pop()defstartPage(self,attrs):print'startPage'filename=os.path.join(*self.directory+[attrs['name']+'.html'])self.out=open(filename,'w')self.writeHeader(attrs['title'])self.passthrough=TruedefendPage(self):print'endPage'self.passthrough=Falseself.writeFooter()self.out.close()defwriteHeader(self,title):self.out.write('<html>\n <head>\n   <title>')self.out.write(title)self.out.write('</title>\n </head>\n  <body>\n')defwriteFooter(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,传参数时的星号……

2017-05-15更新:

//the5fireblog.b0.upaiyun.com/staticfile/django-tech-end-article.png
- from www.8a72.cn
----EOF-----

微信公众号:Python程序员杂谈

预售优惠价截止到7月8日23点59分。


其他分类:
  • 女子谎称刷单提成骗贫困大学生16万 用于买化妆品 2018-12-01
  • 西安体育学院体育传媒系与西部网签约校媒合作 2018-12-01
  • 网络投票刷礼物能不能帮孩子“争上游”? 2018-11-28
  • 中共山西省委组织部公示 2018-11-28
  • 【北京天气】最新北京今天天气,实时提供北京气温、空气质量、24小时天气预报、生活指数查询 2018-11-24
  • 格局生变 内容产业未来何去何从 2018-08-18
  • 土地不是劳动成果,而是一种自然资源,就像空气、阳光不是劳动成果而是自然资源一样,所以土地不具有价值,买房只应支付房屋费,不应该支付土地费。 2018-08-14
  • 安全生产月:铁路安全宣传走进车站 2018-08-02
  • 带动乡亲干 各自有实招——三位农村社区党组织书记的故事 2018-08-02
  • 长江中下游正式“入梅”!中东部高温降雨齐上阵 湖北中北部有大到暴雨 2018-07-31
  • 2018年4月27日划拨国家社科基金项目鉴定费名单(2) 2018-07-31
  • [微笑]未来的社会,必然是按需(基本需求)分配+按劳(劳动价值或劳动能力)分配相联合的混合分配方式。 2018-07-30
  • “一带一路”建设工作座谈会 2018-07-30
  • 只要等一等就能多“等”出8600万美元! 2018-07-29
  • 2017年秋季学期学员第十三支部风采 2018-07-18
  • 184| 951| 55| 826| 252| 90| 461| 484| 253| 831|