python基础教程项目三之万能的XML


Posted in Python onApril 02, 2018

这个项目的名称与其叫做万能的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 ContentHandler
from xml.sax import parse
import os
class 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,传参数时的星号……

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
pydev使用wxpython找不到路径的解决方法
Feb 10 Python
Python入门篇之文件
Oct 20 Python
Python正规则表达式学习指南
Aug 02 Python
Python读取视频的两种方法(imageio和cv2)
Apr 15 Python
对Python 2.7 pandas 中的read_excel详解
May 04 Python
Pandas读取并修改excel的示例代码
Feb 17 Python
python常用数据重复项处理方法
Nov 22 Python
解决Python import docx出错DLL load failed的问题
Feb 13 Python
python框架flask入门之路由及简单实现方法
Jun 07 Python
PyQt5多线程防卡死和多窗口用法的实现
Sep 15 Python
python 模块重载的五种方法
Apr 24 Python
教你如何用Python实现人脸识别(含源代码)
Jun 23 Python
python opencv检测目标颜色的实例讲解
Apr 02 #Python
浅谈python配置与使用OpenCV踩的一些坑
Apr 02 #Python
python基础教程项目二之画幅好画
Apr 02 #Python
通过Python 接口使用OpenCV的方法
Apr 02 #Python
Python 3.x 安装opencv+opencv_contrib的操作方法
Apr 02 #Python
在python3.5中使用OpenCV的实例讲解
Apr 02 #Python
Python-OpenCV基本操作方法详解
Apr 02 #Python
You might like
php分页函数示例代码分享
2014/02/24 PHP
ThinkPHP CURD方法之where方法详解
2014/06/18 PHP
修改destoon会员公司的伪静态中的com目录的方法
2014/08/21 PHP
curl和libcurl的区别简介
2015/07/01 PHP
JavaScript 数组的 uniq 方法
2008/01/23 Javascript
基于JQuery实现相同内容合并单元格的代码
2011/01/12 Javascript
javascript小组件 原生table排序表格脚本(兼容ie firefox opera chrome)
2012/07/25 Javascript
IE中鼠标经过option触发mouseout的解决方法
2015/01/29 Javascript
Web前端开发工具——bower依赖包管理工具
2016/03/29 Javascript
在Docker快速部署Node.js应用的详细步骤
2016/09/02 Javascript
图片懒加载插件实例分享(含解析)
2017/01/09 Javascript
AngularJS中$http使用的简单介绍
2017/03/17 Javascript
微信小程序之判断页面滚动方向的示例代码
2018/08/30 Javascript
[04:52]DOTA2亚洲邀请赛附加赛 TOP10精彩集锦
2015/01/29 DOTA
[50:21]Liquid vs Winstrike 2018国际邀请赛小组赛BO2 第二场
2018/08/19 DOTA
python机器学习实战之K均值聚类
2017/12/20 Python
Python爬虫_城市公交、地铁站点和线路数据采集实例
2018/01/10 Python
详解Python中的内建函数,可迭代对象,迭代器
2019/04/29 Python
python打开windows应用程序的实例
2019/06/28 Python
python实现两张图片拼接为一张图片并保存
2019/07/16 Python
基于python生成英文版词云图代码实例
2020/05/16 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
2020/06/08 Python
使用豆瓣源来安装python中的第三方库方法
2021/01/26 Python
出门问问全球官方商城:Tichome音箱和TicWatch智能手表
2017/12/02 全球购物
毕业生找工作的自我评价
2013/10/18 职场文书
电子商务专业自荐信
2014/06/02 职场文书
卫生院艾滋病宣传活动小结
2014/07/09 职场文书
竞选班干部演讲稿100字
2014/08/20 职场文书
单位作风建设自查报告
2014/10/23 职场文书
2015年初一班主任工作总结
2015/05/13 职场文书
感恩教育主题班会
2015/08/12 职场文书
2015质检员个人年终工作总结
2015/10/23 职场文书
JavaScript原始值与包装对象的详细介绍
2021/05/11 Javascript
MySQL连接查询你真的学会了吗?
2021/06/02 MySQL
JavaScript选择器函数querySelector和querySelectorAll
2021/11/27 Javascript
Win11 Build 22000.829更新补丁KB5015882发布(附更新修复内容汇总)
2022/07/15 数码科技