这个项目的名称与其叫做万能的XML不如叫做自动构建网站,根据一份XML文件,生成对应目录结构的网站,不过只有html还是太过于简单了,如果要是可以连带生成css那就比较强大了。这个有待后续研发,先来研究下怎么html网站结构,既然是通过XML结构生成网站,那所有的事情都应该由这个XML文件来。先来看下这个XML文件,网站。xml:
& lt; website> & lt;页面名称="指数" title=爸饕场北? & lt; h2>欢迎来我家page & lt; p>你好,。我叫Mr.gumby,,这是我的主页,这里有一些我的int: & lt;/p> & lt; ul> & lt; li> & lt; a href=" https://www.yisu.com/zixun/interests/shouting.html " rel=巴獠縩ofollow”祝辞Shouting & lt;/li> & lt; li> & lt; a href=" https://www.yisu.com/zixun/interests/sleeping.html " rel=巴獠縩ofollow”祝辞Sleeping & lt;/li> & lt; li> & lt; a href=" https://www.yisu.com/zixun/interests/eating.html " rel=巴獠縩ofollow”祝辞Eating & lt;/li> & lt;/ul> & lt;/page> & lt;目录名称=袄妗北? & lt;页面名称="高喊“title=按蠛按蠼小北? & lt; h2>大喊page & lt; p> .... & lt;/p> & lt;/page> & lt;页面name="睡觉" title=八痹? & lt; h2>睡觉page & lt; p>……& lt;/p> & lt;/page> & lt;页面名称="吃" title=俺浴北? & lt; h2>吃page & lt; p> .... & lt;/p> & lt;/page> & lt;/directory> & lt;/website> >之前有了这个文件,下面应该来看怎么通过这个文件生成网站。
首先我们要解析这个xml文件,python解析xml和java中在一样,有两种方式,SAX和DOM,两种处理方式不同点在于速度和范围,前者讲究的是效率,每次只处理文档的一小部分,快速而能有效的利用内存,后者是相反的处理方式,先把所有的文档载入到内存,然后再进行处理,速度比较慢,也比较消耗内存,唯一的好处就是可以操作整个文档。
在python中使用sax方式处理xml要先引入sax中的解析函数,还有sax。处理程序中的ContentHandler,后面的这个类是要和解析函数来配合使用的。使用方式如下:解析(xxx.xml, xxxHandler),这里面的xxxHandler要继承上面的ContentHandler,不过只要继承就行,不需要有所作为,然后这个解析函数在处理xml文件的时候,会调用xxxHandler中的startElement函数和endElement函数来一个xml中的标签的开始和结束,中间的过程使用一个名为字符的函数来处理标签内部的所有字符串。
有了上面的这些认识,我们已经知道如何处理xml文件了,然后再来看那个罪恶的源头网站。xml文件,分析其结构,只有两个节点:页和目录,很明显页表示一个页面,目录表示一个目录。
所以处理这个xml文件的思路就变的清晰了。读取xml文件的每一个节点,然后判断是页面还是目录如果是页面则创建html页面,然后把节点中的内容写到文件里。如果遇到目录就创建一个文件夹,然后再处理其内部的页面节点(如果存在的话)。
下面来看这部分代码,书中的实现比较复杂,比较灵活。先来看,然后在分析。
从sax。处理程序导入ContentHandler 从xml。进口sax解析 进口操作系统 类调度程序: def调度(自我,前缀,名字,attrs=None): mname=前缀+ name.capitalize () dname=稀? prefix.capitalize () 方法=getattr(自我,mname,没有) 如果调用(方法):args=() 其他: 方法=getattr(自我,dname,没有) args=名字, 如果前缀==翱肌?args +=attrs, 如果调用(方法):方法(* args) def startElement(自我、名称、attrs): 自我。调度(‘开始’,名字,attrs) def endElement(自我、名称): 自我。调度(“结束”,名称) 类WebsiteConstructor(调度员,ContentHandler): 透传=False def __init__(自我、目录): 自我。目录=(目录) self.ensureDirectory () def ensureDirectory(自我): 路径=os.path.join (* self.directory) 打印路径 打印“- - - - -” 如果不是os.path.isdir(路径):os.makedirs(路径) def字符(自我,字符): 如果自我。透传:self.out.write(字符) def defaultStart(自我、名称、attrs): 如果self.passthrough: self.out.write (' & lt; ' +名字) 关键,val attrs.items (): self.out。写(“% s”=? s”%(关键,val)) self.out.write(在) def defaultEnd(自我、名称): 如果self.passthrough: self.out.write (' & lt;/% s> ' %的名字) def startDirectory(自我,attrs): self.directory.append (attrs['名字']) self.ensureDirectory () def endDirectory(自我): 打印“endDirectory” self.directory.pop () def startPage(自我,attrs): 打印“startPage” 文件名=os.path.join(*自我。目录+ [attrs(“名字”)+ ' . html ']) 自我。=开放(文件名,“w”) self.writeHeader (attrs['标题']) 自我。透传=True def endPage(自我): 打印“endPage” 自我。透传=False self.writeFooter () self.out.close () def writeHeader(自我、标题): self.out.write (' & lt; html> \ n & lt; head> \ n & lt; title>”) self.out.write(标题) self.out.write (' & lt;/title> \ n & lt;/head> \ n & lt; body> \ n”) def writeFooter(自我): self.out。写(“\ n & lt;/body> \ npython基础教程项目三之万能的XML