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 代码性能优化技巧分享
Aug 07 Python
python实现无证书加密解密实例
Oct 27 Python
Windows下安装python2.7及科学计算套装
Mar 05 Python
Python中的复制操作及copy模块中的浅拷贝与深拷贝方法
Jul 02 Python
python之Character string(实例讲解)
Sep 25 Python
Python利用字典将两个通讯录文本合并为一个文本实例
Jan 16 Python
Python实现的栈(Stack)
Jan 26 Python
Python实现判断一行代码是否为注释的方法
May 23 Python
Python 获取中文字拼音首个字母的方法
Nov 28 Python
利用Python实现微信找房机器人实例教程
Mar 10 Python
python与C、C++混编的四种方式(小结)
Jul 15 Python
Pyhton爬虫知识之正则表达式详解
Apr 01 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中常用数组处理方法实例分析
2008/08/30 PHP
Wordpress php 分页代码
2009/10/21 PHP
PHP的压缩函数实现:gzencode、gzdeflate和gzcompress的区别
2016/01/27 PHP
JavaScript 类型的包装对象(Typed Wrappers)
2011/10/27 Javascript
js Form.elements[i]的使用实例
2011/11/13 Javascript
js将iframe中控件的值传到主页面控件中的实现方法
2013/03/11 Javascript
javascript模拟订火车票和退票示例
2014/04/24 Javascript
jQuery.holdReady()使用方法
2014/05/20 Javascript
基于jquery实现发送文章到手机的代码
2014/12/26 Javascript
JavaScript中Function详解
2015/02/27 Javascript
JS根据浏览器窗口大小实时动态改变网页文字大小的方法
2016/02/25 Javascript
node.js中module.exports与exports用法上的区别
2016/09/02 Javascript
jQuery实现一个简单的轮播图
2017/02/19 Javascript
关于JavaScript中forEach和each用法浅析
2017/07/27 Javascript
ReactJs实现树形结构的数据显示的组件的示例
2017/08/18 Javascript
jQuery实现的下雪动画效果示例【附源码下载】
2018/02/02 jQuery
如何编写一个d.ts文件的步骤详解
2018/04/13 Javascript
总结javascript三元运算符知识点
2018/09/28 Javascript
微信小程序 函数防抖 解决重复点击消耗性能问题实现代码
2019/09/12 Javascript
原生js实现自定义滚动条
2021/01/20 Javascript
[02:17]2016完美“圣”典风云人物:Sccc专访
2016/12/03 DOTA
[30:55]完美世界DOTA2联赛PWL S2 Magma vs LBZS 第二场 11.18
2020/11/18 DOTA
python使用paramiko模块实现ssh远程登陆上传文件并执行
2014/01/27 Python
对python的bytes类型数据split分割切片方法
2018/12/04 Python
python程序中的线程操作 concurrent模块使用详解
2019/09/23 Python
Python的形参和实参使用方式
2019/12/24 Python
python3代码输出嵌套式对象实例详解
2020/12/03 Python
解决Firefox下不支持outerHTML问题代码分享
2014/06/04 HTML / CSS
将相和教学反思
2014/02/04 职场文书
法律进学校实施方案
2014/03/15 职场文书
竞选学生会主席演讲稿
2014/04/24 职场文书
物流业务员岗位职责
2015/04/03 职场文书
勤俭节约倡议书范文
2015/04/29 职场文书
2015企业年终工作总结范文
2015/05/27 职场文书
环保建议书作文500字
2015/09/14 职场文书
Nginx如何配置根据路径转发详解
2022/07/23 Servers