python3解析xml_python练习三—解析xml

使用python解析xml,主要使用sax的ContentHandler中的标签开始和标签结束的方法驱动,然后在开始(或者结束)事件中决定使用什么处理方法,使用dispatcher来决定并分发到指定方法内处理处理流程如下:

初始化的时候创建一个目录list

遇到page在当前目录下新建一个html文件,标志接下来的标签是要使用default处理,写到html页面中

遇到page内部的标签,使用default处理

遇到page结束标签,该html写完,填充结尾标签,关闭流

遇到directory标签,往directory的list】中添加下以及目录名称

遇到page重复第1,2,3步

解析完成

代码如下

#! /usr/bin/env python#-*- coding=utf-8 -*-

importosimportsysfrom xml.sax.handler importContentHandlerfrom xml.sax importparseclassDispatcher:'''根据具体的xml标签分发到具体的解析函数解析'''

def dispatch(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,#如果是调用开始处理函数, 需要传递该标签的属性

if prefix == 'start':

args+=attrs,ifcallable(method):

method(*args)#重载父类的startElement方法

defstartElement(self, name, attrs):

self.dispatch('start', name, attrs)#重载父类的endElement方法

defendElement(self, name):

self.dispatch('end', name)classWebsiteConstructor(Dispatcher, ContentHandler):'''分析website.xml构建html网页'''

#该标签是否是正文,是否被page包裹,是否需要解析

passthrough =Falsedef __init__(self, directory):

self.directory=[directory]

self.ensureDirectory()defensureDirectory(self):

path= os.path.join(*self.directory)if notos.path.isdir(path):

os.makedirs(path)defcharacters(self, chars):ifself.passthrough:

self.out.write(chars)defdefaultStart(self, name, attrs):ifself.passthrough:

self.out.write('

printattrsfor key, val inattrs.items():

self.out.write('%s=%s' %(key, val))printkey,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):

self.directory.pop()defstartPage(self, attrs):

filename= os.path.join(*self.directory + [attrs['name'] + '.html'])

self.out= open(filename, 'w')printos.pathprintfilenameprintself.directoryprint self.directory + [attrs['name'] + '.html']

self.writeHeader(attrs['title'])

self.passthrough=TruedefendPage(self):

self.passthrough=False

self.writeFooter()

self.out.close()defwriteHeader(self, title):

self.out.write('\n

\n ')

self.out.write(title)

self.out.write('

\n \n \n')defwriteFooter(self):

self.out.write('\n \n\n')#执行程序

parse('website.xml', WebsiteConstructor('public_html'))

参照书中写完代码之后,发现"args +=attrs"一直报错,调试的时候发现

TypeError: coercing to Unicode: need string or buffer, instance found

在"+="运算符连边需要的是string或者buffer,实际上是instance,在这条语句里面attrs是AttributesImpl的对象,前面"args = name"将name赋值给args,args是string,所以attrs类型不对,一开始还以为是ContentHandler API改变了(因为该书已经比较早了),在ipython交互命令行中查看帮助文档,发现没有错,折腾调试了挺久,对照书中源码发现有两处少了",",当时已经疯了。。。。。

args =name,

args+= attrs,

少了上面两个逗号,内心的崩溃啊,由此可见自己python基本知识还是漏了

args = name #args仅仅是一个对象,并不是元组

args = name, #args是一个元组

一个逗号引发的血案。。。。。

还有就是"+=",该运算符两边类型必须一致,都是字符串(列表,元组)

完整代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值