python解析xml模块封装代码


Posted in Python onFebruary 07, 2014

有如下的xml文件:

<?xml version="1.0" encoding="utf-8" ?>  
<root>  
<childs>  
<child name='first' >1</child>  
<child value="2">2</child>  
</childs>  
</root>

下面介绍python解析xml文件的几种方法,使用python模块实现。

方式1,python模块实现自动遍历所有节点:

#!/usr/bin/env python  
# -*- coding: utf-8 -*-  
from xml.sax.handler import ContentHandler  
from xml.sax import parse
class TestHandle(ContentHandler):  
    def __init__(self, inlist):  
        self.inlist = inlist      def startElement(self,name,attrs):  
        print 'name:',name, 'attrs:',attrs.keys()  
    def endElement(self,name):  
        print 'endname',name  
    def characters(self,chars):  
        print 'chars',chars  
        self.inlist.append(chars)  
              
if __name__ == '__main__':  
    lt = []  
    parse('test.xml', TestHandle(lt))  
    print lt

结果:
[html] view plaincopy
name: root attrs: [] 
chars  

name: childs attrs: [] 
chars  

name: child attrs: [u'name'] 
chars 1 
endname child 
chars  

name: child attrs: [u'value'] 
chars 2 
endname child 
chars  

endname childs 
chars  

endname root 
[u'\n', u'\n', u'1', u'\n', u'2', u'\n', u'\n']

方式2,python模块实现获取根节点,按需查找指定节点:

#!/usr/bin/env python    
# -*- coding: utf-8 -*-    
from xml.dom import minidom    
xmlstr = '''''<?xml version="1.0" encoding="UTF-8"?> 
<hash> 
    <request name='first'>/2/photos/square/type.xml</request> 
    <error_code>21301</error_code> 
    <error>auth faild!</error> 
</hash> 
'''  
def doxml(xmlstr):  
    dom = minidom.parseString(xmlstr)      
    print 'Dom:'      
    print dom.toxml()        root = dom.firstChild      
    print 'root:'      
    print root.toxml()    
    childs = root.childNodes    
    for child in childs:  
        print child.toxml()  
        if child.nodeType == child.TEXT_NODE:  
            pass  
        else:  
            print 'child node attribute name:', child.getAttribute('name')  
            print 'child node name:', child.nodeName  
            print 'child node len:',len(child.childNodes)  
            print 'child data:',child.childNodes[0].data  
            print '======================================='  
            print 'more help info to see:'  
            for med in dir(child):  
                print help(med)      
                
if __name__ == '__main__':    
    doxml(xmlstr)

结果:
[html] view plaincopy
Dom: 
<?xml version="1.0" ?><hash> 
    <request name="first">/2/photos/square/type.xml</request> 
    <error_code>21301</error_code> 
    <error>auth faild!</error> 
</hash> 
root: 
<hash> 
    <request name="first">/2/photos/square/type.xml</request> 
    <error_code>21301</error_code> 
    <error>auth faild!</error> 
</hash> 

<request name="first">/2/photos/square/type.xml</request> 
child node attribute name: first 
child node name: request 
child node len: 1 
child data: /2/photos/square/type.xml 
======================================= 
more help info to see: 
两种方法各有其优点,python的xml处理模块太多,目前只用到这2个。

=====补充分割线================
实际工作中发现python的mimidom无法解析其它编码的xml,只能解析utf-8的编码,而其xml文件的头部申明也必须是utf-8,为其它编码会报错误。
网上的解决办法都是替换xml文件头部的编码申明,然后转换编码为utf-8再用minidom解码,实际测试为可行,不过有点累赘的感觉。

本节是 python解析xml模块封装代码 的第二部分。
====写xml内容的分割线=========

#!\urs\bin\env python  
#encoding: utf-8  
from xml.dom import minidom  class xmlwrite:  
    def __init__(self, resultfile):  
        self.resultfile = resultfile  
        self.rootname = 'api'  
        self.__create_xml_dom()  
    def __create_xml_dom(self):  
        xmlimpl = minidom.getDOMImplementation()  
        self.dom = xmlimpl.createDocument(None, self.rootname, None)  
        self.root = self.dom.documentElement  
    def __get_spec_node(self, xpath):  
        patharr = xpath.split(r'/')  
        parentnode = self.root  
        exist = 1  
        for nodename in patharr:  
            if nodename.strip() == '':  
                continue  
            if not exist:  
                return None  
            spcindex = nodename.find('[')  
            if spcindex > -1:  
                index = int(nodename[spcindex+1:-1])  
            else:  
                index = 0  
            count = 0  
            childs = parentnode.childNodes  
            for child in childs:  
                if child.nodeName == nodename[:spcindex]:  
                    if count == index:  
                        parentnode = child  
                        exist = 1  
                        break  
                    count += 1  
                    continue  
                else:  
                    exist = 0  
        return parentnode  
          
    def write_node(self, parent, nodename, value, attribute=None, CDATA=False):  
        node = self.dom.createElement(nodename)  
        if value:  
            if CDATA:  
                nodedata = self.dom.createCDATASection(value)  
            else:  
                nodedata = self.dom.createTextNode(value)  
            node.appendChild(nodedata)  
            if attribute and isinstance(attribute, dict):  
                for key, value in attribute.items():  
                    node.setAttribute(key, value)     
        try:  
            parentnode = self.__get_spec_node(parent)  
        except:  
            print 'Get parent Node Fail, Use the Root as parent Node'  
            parentnode = self.root  
        parentnode.appendChild(node)  
      
    def write_start_time(self, time):  
        self.write_node('/','StartTime', time)  
    def write_end_time(self, time):  
        self.write_node('/','EndTime', time)      
    def write_pass_count(self, count):  
        self.write_node('/','PassCount', count)     
    def write_fail_count(self, count):  
        self.write_node('/','FailCount', count)     
    def write_case(self):  
        self.write_node('/','Case', None)     
    def write_case_no(self, index, value):  
        self.write_node('/Case[%s]/' % index,'No', value)  
    def write_case_url(self, index, value):  
        self.write_node('/Case[%s]/' % index,'URL', value)  
    def write_case_dbdata(self, index, value):  
        self.write_node('/Case[%s]/' % index,'DBData', value)  
    def write_case_apidata(self, index, value):  
        self.write_node('/Case[%s]/' % index,'APIData', value)  
    def write_case_dbsql(self, index, value):  
        self.write_node('/Case[%s]/' % index,'DBSQL', value, CDATA=True)  
    def write_case_apixpath(self, index, value):  
        self.write_node('/Case[%s]/' % index,'APIXPath', value)         
    def save_xml(self):  
        myfile = file(self.resultfile, 'w')  
        self.dom.writexml(myfile, encoding='utf-8')  
        myfile.close()  
if __name__ == '__main__':  
      xr = xmlwrite(r'D:\test.xml')  
      xr.write_start_time('2223')  
      xr.write_end_time('444')        
      xr.write_pass_count('22')  
      xr.write_fail_count('33')    
      xr.write_case()  
      xr.write_case()  
      xr.write_case_no(0, '0')  
      xr.write_case_url(0, 'http://www.google.com')     
      xr.write_case_url(0, 'http://www.google.com')     
      xr.write_case_dbsql(0, 'select * from ')  
      xr.write_case_dbdata(0, 'dbtata')  
      xr.write_case_apixpath(0, '/xpath')  
      xr.write_case_apidata(0, 'apidata')  
      xr.write_case_no(1, '1')         
      xr.write_case_url(1, 'http://www.baidu.com')     
      xr.write_case_url(1, 'http://www.baidu.com')     
      xr.write_case_dbsql(1, 'select 1 from ')  
      xr.write_case_dbdata(1, 'dbtata1')  
      xr.write_case_apixpath(1, '/xpath1')  
      xr.write_case_apidata(1, 'apidata1')  
      xr.save_xml()

以上封装了minidom,支持通过xpath来写节点,不支持xpath带属性的匹配,但支持带索引的匹配。
比如:/root/child[1], 表示root的第2个child节点。

Python 相关文章推荐
将Python代码打包为jar软件的简单方法
Aug 04 Python
Python列出一个文件夹及其子目录的所有文件
Jun 30 Python
Python设计模式之抽象工厂模式
Aug 25 Python
python爬虫之自动登录与验证码识别
Jun 15 Python
python按照多个条件排序的方法
Feb 08 Python
在python里面运用多继承方法详解
Jul 01 Python
linux中如何使用python3获取ip地址
Jul 15 Python
使用turtle绘制五角星、分形树
Oct 06 Python
pytorch-RNN进行回归曲线预测方式
Jan 14 Python
Python新手学习标准库模块命名
May 29 Python
python中numpy.empty()函数实例讲解
Feb 05 Python
Golang Web 框架Iris安装部署
Aug 14 Python
python 解析XML python模块xml.dom解析xml实例代码
Feb 07 #Python
python合并文本文件示例
Feb 07 #Python
python实现哈希表
Feb 07 #Python
python处理cookie详解
Feb 07 #Python
urllib2自定义opener详解
Feb 07 #Python
python解析html开发库pyquery使用方法
Feb 07 #Python
python3.3实现乘法表示例
Feb 07 #Python
You might like
php代码收集表单内容并写入文件的代码
2012/01/29 PHP
PHP中HTML标签过滤技巧
2014/01/07 PHP
php调用google接口生成二维码示例
2014/04/28 PHP
完美解决在ThinkPHP控制器中命名空间的问题
2017/05/05 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
javascript 获取函数形参个数
2014/07/31 Javascript
Javascript中数组sort和reverse用法分析
2014/12/30 Javascript
为输入框加入数字js校验代码分享
2017/11/02 Javascript
vue中手机号,邮箱正则验证以及60s发送验证码的实例
2018/03/16 Javascript
Vue列表渲染的示例代码
2018/11/01 Javascript
vue中将html字符串转换成html后遇到的问题小结
2018/12/10 Javascript
vue App.vue中的公共组件改变值触发其他组件或.vue页面监听
2019/05/31 Javascript
详解JavaScript之ES5的继承
2020/07/08 Javascript
vue将文件/图片批量打包下载zip的教程
2020/10/21 Javascript
[10:34]DOTA2上海特级锦标赛全纪录
2016/03/25 DOTA
[57:37]EG vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[42:23]完美世界DOTA2联赛PWL S3 Forest vs Rebirth 第二场 12.10
2020/12/13 DOTA
用python代码做configure文件
2014/07/20 Python
python中使用xlrd、xlwt操作excel表格详解
2015/01/29 Python
django+echart绘制曲线图的方法示例
2018/11/26 Python
Python函数中不定长参数的写法
2019/02/13 Python
Python selenium的基本使用方法分析
2019/12/21 Python
PyTorch 对应点相乘、矩阵相乘实例
2019/12/27 Python
基于python 等频分箱qcut问题的解决
2020/03/03 Python
python安装dlib库报错问题及解决方法
2020/03/16 Python
python实现坦克大战
2020/04/24 Python
基于python调用jenkins-cli实现快速发布
2020/08/14 Python
浅谈对python中if、elif、else的误解
2020/08/20 Python
使用CSS3来制作消息提醒框
2015/07/12 HTML / CSS
eBay比利时购物网站:eBay.be
2019/08/09 全球购物
优秀民警事迹材料
2014/01/29 职场文书
团队队名口号大全
2014/06/06 职场文书
管理标语大全
2014/06/24 职场文书
责任书范本大全
2015/05/11 职场文书
2016年八一建军节活动总结
2016/04/05 职场文书
win10如何更改appdata文件夹的默认位置?
2022/07/15 数码科技