Python处理XML格式数据的方法详解


Posted in Python onMarch 21, 2017

本文实例讲述了Python处理XML格式数据的方法。分享给大家供大家参考,具体如下:

这里的操作是基于Python3平台。

在使用Python处理XML的问题上,首先遇到的是编码问题。

Python并不支持gb2312,所以面对encoding="gb2312"的XML文件会出现错误。Python读取的文件本身的编码也可能导致抛出异常,这种情况下打开文件的时候就需要指定编码。此外就是XML中节点所包含的中文。

我这里呢,处理就比较简单了,只需要修改XML的encoding头部。

#!/usr/bin/env python
import os, sys
import re
def replaceXmlEncoding(filepath, oldEncoding='gb2312', newEncoding='utf-8'):
  f = open(filepath, mode='r')
  content = f.read()
  content = re.sub(oldEncoding, newEncoding, content)
  f.close()
  f = open(filepath, mode='w')
  f.write(content)
  f.close()
if __name__ == "__main__":
  replaceXmlEncoding('./ActivateAccount.xml')

接着是使用xml.etree.ElementTree来操作XML文件。

在一个类里面定义__call__函数可以使得该类可调用,比如下面代码的最后几行,在__main__函数中。这也很突出地体现了在Python的世界里,一切都是对象,包括对象本身 :)

一直觉得__main__函数用来测试真是蛮好用的。

#!/usr/bin/env python
import os, re
import xml.etree.ElementTree as etree
Locale_Path = "./locale.txt"
class xmlExtractor(object):
  def __init__(self):
    pass
  def __call__(self, filepath):
    retDict = {}
    f = open(filepath, 'r')
    Line = len(open(filepath, 'r').readlines())
    retDict['Line'] = Line
    tree = etree.parse(f)
    root = tree.find("ResItem")
    Id = root.get("ID")
    retDict['Title'] = Id
    resItemCnt = len(list(root.findall("ResItem"))) + 1
    retDict['ResItemCount'] = resItemCnt
    retDict['ChineseTip'] = 'None'
    for child in root:
      attrDict = child.attrib
      keyword = "Name"
      if(keyword in attrDict.keys() and attrDict['Name'] == "Caption"):
        if len(child.attrib['Value']) > 1:
          if child.attrib['Value'][0] == '~':
            title = child.attrib['Value'][1:]
          else:
            title = child.attrib['Value'][0:]
          #print(title)
          chs = open(Locale_Path).read()
          pattern = '<String id="' + title + '">[^>]+>'
          m = re.search(pattern, chs)
          if m != None:
            realTitle = re.sub('<[^>]+>', '', m.group(0))
            retDict['ChineseTip'] = realTitle
    f.close()
    return retDict
if __name__ == "__main__":
  fo = xmlExtractor()
  d = fo('./ActivateAccount.xml')
  print(d)

最后,就是入口文件,导入上面两个文件,使用xml.dom和os.listdir来递归处理XML文件,并生成一个结果集。

一直觉得Python的UnboundLocalError错误挺有意思的,不知道是不是符号表的覆盖问题。

#!/usr/bin/env python
from xmlExtractor import *
from replaceXmlEncoding import *
from xml.dom import minidom,Node
doc = minidom.Document()
extractor = xmlExtractor()
totalLines = 0
totalResItemCnt = 0
totalXmlFileCnt = 0
totalErrorCnt = 0
errorFileList = []
xmlRoot = doc.createElement("XmlResourceFile")
doc.appendChild(xmlRoot)
def myWalkDir(level, path):
  global doc, extractor, totalLines, totalResItemCnt, totalXmlFileCnt
  global totalErrorCnt, errorFileList
  global xmlRoot
  for i in os.listdir(path):
    if i[-3:] == 'xml':
      totalXmlFileCnt += 1
      try:
        #先把xml的encoding由gb2312转换为utf-8
        replaceXmlEncoding(path + '\\' + i)
        #再提取xml文档中需要的信息
        info = extractor(path + '\\' + i)
        #在上述两行代码没有出现异常的基础上再创建节点
        #print(info)
        #print(type(i))
        xmlNode = doc.createElement("XmlFile")
        xmlRoot.appendChild(xmlNode)
        xmlName = doc.createElement("Filename")
        xmlName.setAttribute('Value', i)
        #xmlName.appendChild(doc.createTextNode(i))
        xmlNode.appendChild(xmlName)
        filePath = doc.createElement("Filepath")
        filePath.setAttribute('Value', path[34:])
        #filePath.appendChild(doc.createTextNode(path[1:]))
        xmlNode.appendChild(filePath)
        titleNode = doc.createElement("Title")
        titleNode.setAttribute('Value', str(info['Title']))
        #titleNode.appendChild(doc.createTextNode(str(info['Title'])))
        xmlNode.appendChild(titleNode)
        chsNode = doc.createElement("ChineseTip")
        chsNode.setAttribute('Value', str(info['ChineseTip']))
        #chsNode.appendChild(doc.createTextNode(str(info['Chinese'])))
        xmlNode.appendChild(chsNode)
        resItemNode = doc.createElement("ResItemCount")
        resItemNode.setAttribute('Value', str(info['ResItemCount']))
        #resItemNode.appendChild(doc.createTextNode(str(info['ResItemCount'])))
        xmlNode.appendChild(resItemNode)
        lineNode = doc.createElement("LineCount")
        lineNode.setAttribute('Value', str(info['Line']))
        #lineNode.appendChild(doc.createTextNode(str(info['Line'])))
        xmlNode.appendChild(lineNode)
        descNode = doc.createElement("Description")
        descNode.setAttribute('Value', '')
        #descNode.appendChild(doc.createTextNode(''))
        xmlNode.appendChild(descNode)
      except Exception as errorDetail:
        totalErrorCnt += 1
        errorFileList.append(path + '\\' + i)
        print(path + '\\' + i, errorDetail)
    if os.path.isdir(path + '\\' + i):
      myWalkDir(level+1, path + '\\' + i)
if __name__ == "__main__":
  path = os.getcwd() + '\\themes'
  myWalkDir(0, path)
  print(totalXmlFileCnt, totalErrorCnt)
  #print(doc.toprettyxml(indent = "  "))
  resultXml = open("./xmlResourceList.xml", "w")
  resultXml.write(doc.toprettyxml(indent = "  "))
  resultXml.close()
Python 相关文章推荐
Python base64编码解码实例
Jun 21 Python
python 线程的暂停, 恢复, 退出详解及实例
Dec 06 Python
python中requests库session对象的妙用详解
Oct 30 Python
Python实现查询某个目录下修改时间最新的文件示例
Aug 29 Python
Django csrf 验证问题的实现
Oct 09 Python
Python常用特殊方法实例总结
Mar 22 Python
Pandas读写CSV文件的方法示例
Mar 27 Python
Python+Pyqt实现简单GUI电子时钟
Feb 22 Python
python字典的遍历3种方法详解
Aug 10 Python
Pandas的Apply函数具体使用
Jul 21 Python
通过代码实例解析Pytest运行流程
Aug 20 Python
python 调用API接口 获取和解析 Json数据
Sep 28 Python
Python做简单的字符串匹配详解
Mar 21 #Python
Python 转义字符详细介绍
Mar 21 #Python
python 迭代器和iter()函数详解及实例
Mar 21 #Python
浅谈五大Python Web框架
Mar 20 #Python
python rsa 加密解密
Mar 20 #Python
Python 专题六 局部变量、全局变量global、导入模块变量
Mar 20 #Python
python list排序的两种方法及实例讲解
Mar 20 #Python
You might like
php数组的一些常见操作汇总
2011/07/17 PHP
PHP的array_diff()函数在处理大数组时的效率问题
2011/11/27 PHP
php判断GIF图片是否为动画的方法
2020/09/04 PHP
Yii调试SQL的常用方法
2014/07/09 PHP
PHP中使用虚代理实现延迟加载技术
2014/11/05 PHP
基于PHP实现简单的随机抽奖小程序
2016/01/05 PHP
可以文本显示的公告栏的js代码
2007/03/11 Javascript
非常不错的功能强大代码简单的管理菜单美化版
2008/07/09 Javascript
JSON JQUERY模板实现说明
2010/07/03 Javascript
jquery 延迟执行实例介绍
2013/08/20 Javascript
jQuery:delegate中select()不起作用的解决方法(实例讲解)
2014/01/26 Javascript
解决jQuery动态获取手机屏幕高和宽的问题
2014/05/07 Javascript
在线所见即所得HTML编辑器的实现原理浅析
2015/04/25 Javascript
javascript类型系统——undefined和null全面了解
2016/07/13 Javascript
jquery实用技巧之输入框提示语句
2016/07/28 Javascript
JavaScript的事件机制详解
2017/01/17 Javascript
Angularjs验证用户输入的字符串是否为日期时间
2017/06/01 Javascript
vue 中的keep-alive实例代码
2018/07/20 Javascript
微信小程序实现商品属性联动选择
2019/02/15 Javascript
基于mpvue搭建微信小程序项目框架的教程详解
2019/04/10 Javascript
JSONP 的原理、理解 与 实例分析
2020/05/16 Javascript
用Python设计一个经典小游戏
2017/05/15 Python
python3常用的数据清洗方法(小结)
2019/10/31 Python
python模块和包的应用BASE_PATH使用解析
2019/12/14 Python
CSS3 实现童年的纸飞机
2019/05/05 HTML / CSS
茱莉蔻美国官网:Jurlique美国
2020/11/24 全球购物
Java程序员面试90题
2013/10/19 面试题
Ajax实现页面无刷新留言效果
2021/03/24 Javascript
工业设计专业推荐信
2013/10/29 职场文书
机关门卫制度
2014/02/01 职场文书
《黄河颂》教学反思
2014/02/07 职场文书
西式结婚主持词
2014/03/14 职场文书
营销团队口号
2014/06/06 职场文书
德育标兵事迹材料
2014/08/24 职场文书
2014年销售工作总结范文
2014/12/01 职场文书
暑期辅导班宣传单
2015/07/14 职场文书