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内存管理分析
Apr 08 Python
Python程序退出方式小结
Dec 09 Python
python实现随机漫步算法
Aug 27 Python
tensorflow实现加载mnist数据集
Sep 08 Python
Python使用crontab模块设置和清除定时任务操作详解
Apr 09 Python
Python中字符串与编码示例代码
May 20 Python
简单了解django索引的相关知识
Jul 17 Python
python实现证件照换底功能
Aug 20 Python
python Kmeans算法原理深入解析
Aug 23 Python
你应该知道的Python3.6、3.7、3.8新特性小结
May 12 Python
Python pandas 列转行操作详解(类似hive中explode方法)
May 18 Python
K近邻法(KNN)相关知识总结以及如何用python实现
Jan 28 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
PJBlog插件 防刷新的在线播放器
2006/10/25 Javascript
javascript 伪数组实现方法
2010/10/11 Javascript
jquery ajax 简单范例(界面+后台)
2013/11/19 Javascript
解析Javascript中中括号“[]”的多义性
2013/12/03 Javascript
在JavaScript里防止事件函数高频触发和高频调用的方法
2014/09/06 Javascript
JavaScript如何自定义trim方法
2015/07/28 Javascript
JS实现自动变换的菜单效果代码
2015/09/09 Javascript
值得分享和收藏的Bootstrap学习教程
2016/05/12 Javascript
Bootstrap table学习笔记(2) 前后端分页模糊查询
2017/05/18 Javascript
JavaScript循环_动力节点Java学院整理
2017/06/28 Javascript
JS实现的简单四则运算计算器功能示例
2017/09/27 Javascript
element-ui使用导航栏跳转路由的用法详解
2018/08/22 Javascript
JavaScript实用代码小技巧
2018/08/23 Javascript
vue 利用路由守卫判断是否登录的方法
2018/09/29 Javascript
详解js实时获取并显示当前时间的方法
2019/05/10 Javascript
[01:46]2020完美世界全国高校联赛秋季赛报名开启
2020/10/15 DOTA
python中反射用法实例
2015/03/27 Python
详细讲解用Python发送SMTP邮件的教程
2015/04/29 Python
Python 类的继承实例详解
2017/03/25 Python
Python实用技巧之列表、字典、集合中根据条件筛选数据详解
2018/07/11 Python
python单例模式实例解析
2018/08/28 Python
pandas 条件搜索返回列表的方法
2018/10/30 Python
详解Python下Flask-ApScheduler快速指南
2018/11/04 Python
python实现创建新列表和新字典,并使元素及键值对全部变成小写
2019/01/15 Python
python 多线程对post请求服务器测试并发的方法
2019/06/13 Python
Python Web框架之Django框架Form组件用法详解
2019/08/16 Python
Python操作MySQL数据库的示例代码
2020/07/13 Python
CSS Houdini实现动态波浪纹效果
2019/07/30 HTML / CSS
法国家具及室内配件店:home24
2017/01/21 全球购物
SQL数据库笔试题
2016/03/08 面试题
文明好少年事迹材料
2014/08/19 职场文书
领导干部作风建设自查报告
2014/10/23 职场文书
结婚通知短信怎么写
2015/04/17 职场文书
冲出亚马逊观后感
2015/06/03 职场文书
入门学习Go的基本语法
2021/07/07 Golang
Oracle数据库中通用的函数实例详解
2022/03/25 Oracle