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正则表达式及使用正则表达式的例子
Jan 22 Python
详解django2中关于时间处理策略
Mar 06 Python
django组合搜索实现过程详解(附代码)
Aug 06 Python
Python3直接爬取图片URL并保存示例
Dec 18 Python
使用pyinstaller逆向.pyc文件
Dec 20 Python
解决Pytorch 加载训练好的模型 遇到的error问题
Jan 10 Python
python tqdm 实现滚动条不上下滚动代码(保持一行内滚动)
Feb 19 Python
PyQt使用QPropertyAnimation开发简单动画
Apr 02 Python
python文件操作seek()偏移量,读取指正到指定位置操作
Jul 05 Python
工程师必须了解的LRU缓存淘汰算法以及python实现过程
Oct 15 Python
VSCODE配置Markdown及Markdown基础语法详解
Jan 19 Python
python简单验证码识别的实现过程
Jun 20 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 输出缓存详解
2009/06/20 PHP
php5 图片验证码实现代码
2009/12/11 PHP
php批量上传的实现代码
2013/06/09 PHP
解析MySql与Java的时间类型
2013/06/22 PHP
php截取字符串函数substr,iconv_substr,mb_substr示例以及优劣分析
2014/06/10 PHP
PHP 面向对象程序设计(oop)学习笔记 (四) - 异常处理类Exception
2014/06/12 PHP
YII Framework框架教程之国际化实现方法
2016/03/14 PHP
PHP count()函数讲解
2019/02/03 PHP
Laravel5.7框架安装与使用学习笔记图文详解
2019/04/02 PHP
Laravel向公共模板赋值方法总结
2019/06/25 PHP
根据选择不同的下拉值出现相对应的文本输入框
2013/08/01 Javascript
深入理解JavaScript系列(36):设计模式之中介者模式详解
2015/03/04 Javascript
jQuery实现简单的DIV拖动效果
2016/02/19 Javascript
jQuery简单实现上下,左右滑动的方法
2016/06/01 Javascript
AngularJs concepts详解及示例代码
2016/09/01 Javascript
微信小程序 后台登录(非微信账号)实例详解
2017/03/31 Javascript
用vue封装插件并发布到npm的方法步骤
2017/10/18 Javascript
基于jquery实现五星好评
2017/11/18 jQuery
Bootstrap Table中的多选框删除功能
2018/07/15 Javascript
JavaScript实现京东快递单号查询
2020/11/30 Javascript
[54:25]Ti4 循环赛第三日LGD vs MOUZ
2014/07/12 DOTA
对Python 检查文件名是否规范的实例详解
2019/06/10 Python
解决python多行注释引发缩进错误的问题
2019/08/23 Python
Python实现中值滤波去噪方式
2019/12/18 Python
Ubuntu权限不足无法创建文件夹解决方案
2020/11/14 Python
Python urllib request模块发送请求实现过程解析
2020/12/10 Python
纯css3实现的鼠标悬停动画按钮
2014/12/23 HTML / CSS
林清轩官方网站:山茶花润肤油开创者
2016/10/26 全球购物
德国baby-markt婴儿用品瑞士网站:baby-markt.ch
2017/06/09 全球购物
置业顾问岗位职责
2014/03/02 职场文书
构建和谐校园倡议书
2015/01/19 职场文书
自我检讨书范文
2015/01/28 职场文书
大班下学期个人总结
2015/02/13 职场文书
Python requests库参数提交的注意事项总结
2021/03/29 Python
从np.random.normal()到正态分布的拟合操作
2021/06/02 Python
世界十大狙击步枪排行榜
2022/03/20 杂记