使用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 -*- import os
import sys
from xml.sax.handler import ContentHandler
from xml.sax import parse class Dispatcher:
'''
根据具体的xml标签分发到具体的解析函数解析
''' 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) # 重载父类的startElement方法
def startElement(self, name, attrs):
self.dispatch('start', name, attrs) # 重载父类的endElement方法
def endElement(self, name):
self.dispatch('end', name) class WebsiteConstructor(Dispatcher, ContentHandler):
'''
分析website.xml构建html网页
''' # 该标签是否是正文,是否被page包裹,是否需要解析
passthrough = False def __init__(self, directory):
self.directory = [directory]
self.ensureDirectory() def ensureDirectory(self):
path = os.path.join(*self.directory)
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)
print '-----'
print attrs
for key, val in attrs.items():
self.out.write(' %s=%s' % (key, val))
print 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):
self.directory.pop() def startPage(self, attrs):
filename = os.path.join(*self.directory + [attrs['name'] + '.html'])
self.out = open(filename, 'w')
print os.path
print filename
print self.directory
print self.directory + [attrs['name'] + '.html']
self.writeHeader(attrs['title'])
self.passthrough = True def endPage(self):
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'))

参照书中写完代码之后,发现"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是一个元组

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

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


完整代码

http://pan.baidu.com/s/1pLqxLKv

python练习三—解析xml的更多相关文章

  1. [python]使用ElementTree解析XML【译】

    19.7 The ElementTree XML API 源码:Lib/xml/etree/ElementTree.py Element类型是一个灵活的容器对象,设计出来是用于存储有层次的数据结构到内 ...

  2. python使用SAX解析xml

    python 标准库包含SAX解析器,SAX用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件 在python中使用sax方式处理xml要先引入xml.s ...

  3. ZH奶酪:Python使用ElementTree解析XML【译】

    19.7. xml.etree.ElementTree — The ElementTree XML API 源代码: Lib/xml/etree/ElementTree.py Element类型是一种 ...

  4. Python requests模块解析XML

    检查QQ是否在线(api感觉不准) import requests from xml.etree import ElementTree qq_str = input('please input the ...

  5. python 使用ElementTree解析xml

    以country.xml为例,内容如下: <?xml version="1.0"?> <data> <country name="Liech ...

  6. python 解析xml

    在工作中很多时候都要用到xml,使用这个时候难免会设计到解析他,然后就研究了一下python解析xml问题,看了很多东西,python有很多解析xml的包,但是也折腾我好一段时间,最后选择了这个方法. ...

  7. python 之模块之 xml.dom.minidom解析xml

    # -*- coding: cp936 -*- #python 27 #xiaodeng #python 之模块之 xml.dom.minidom解析xml #http://www.cnblogs.c ...

  8. python解析xml文件时使用ElementTree和cElementTree的不同点;iter

    在python中,解析xml文件时,会选用ElementTree或者cElementTree,那么两者有什么不同呢? 1.cElementTree速度上要比ElementTree快,比较cElemen ...

  9. 用 ElementTree 在 Python 中解析 XML

    用 ElementTree 在 Python 中解析 XML 原文: http://eli.thegreenplace.net/2012/03/15/processing-xml-in-python- ...

随机推荐

  1. 爬取QQ音乐(讲解爬虫思路)

    一.问题描述: 本次爬取的对象是QQmusic,为自己后面做django音乐网站的开发获取一些资源. 二.问题分析: 由于QQmusic和网易音乐的方式差不多,都是讲歌曲信息放入到播放界面播放,在其他 ...

  2. python文件操作打开模式 r,w,a,r+,w+,a+ 区别辨析

    主要分成三大类: r 和 r+     "读"功能 r  只读 r+ 读写(先读后写) 辨析:对于r,只有读取功能,利用光标的移动,可以选择要读取的内容. 对于r+,同时具有读和写 ...

  3. Effective Java -- 使可变性最小化

    为了使类成为不可变的,应该遵循以下五条原则: 1. 不要提供任何会下盖对象状态的方法 2. 保证类不会被扩展 3. 使所有的域都是final的 4. 使所有的域都成为私有的 5. 确保对于任何可变组件 ...

  4. 编写shell脚本kill掉占用cpu超过90%以上的程序

    由于集群用户经常会不懂如何提交作业,将作业直接运行到登录节点上,这样导致登录节点的cpu及内存占用很大,导致其他用户甚至无法登录.所以就想到了一种解决方法,写一个shell脚本,常驻登录节点,监控cp ...

  5. Git使用(一、TortoiseGit和Gitlab在Windows下的项目库创建和上传)

    介绍使用TortoiseGit初次创建并上传到gitlab项目库,转载请注明出处. 一.需要先安装git环境,并配置Git用户名及邮箱. 二.用PuTTYgen生成公约私钥对(鼠标画画).PuTTYg ...

  6. usb 枚举流程简介

    1. 枚举是什么?        枚举就是从设备读取一些信息,知道设备是什么样的设备,如何进行通信,这样主机就可以根据这些信息来加载合适的驱动程序.调试USB设备,很重要的一点就是USB的枚举过程,只 ...

  7. 关于H5在微信获取授权

    很尴尬,flag倒了很久,这才来更新. 1.作为一枚小前端,所做的就是把微信获取授权之后的链接和所需的参数给到后端,定好之后只要获取链接就好了.(⊙o⊙)…确实就是这么简单,基本上这种授权是需要后端来 ...

  8. python 字典中的get()方法

    https://blog.csdn.net/weixin_38705903/article/details/79231551

  9. ios uibutton加数字角标

    http://www.jianshu.com/p/0c7fae1cadac 第一种:https://github.com/mikeMTOL/UIBarButtonItem-Badge第二种:https ...

  10. js获取复选框值

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...