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批量提交沙箱问题实例
Oct 08 Python
Python的Flask框架中实现登录用户的个人资料和头像的教程
Apr 20 Python
Python实现Mysql数据库连接池实例详解
Apr 11 Python
Python通过Django实现用户注册和邮箱验证功能代码
Dec 11 Python
Python中将dataframe转换为字典的实例
Apr 13 Python
Python读写及备份oracle数据库操作示例
May 17 Python
对python字典元素的添加与修改方法详解
Jul 06 Python
selenium跳过webdriver检测并模拟登录淘宝
Jun 12 Python
Flask模板引擎之Jinja2语法介绍
Jun 26 Python
python实现修改固定模式的字符串内容操作示例
Dec 30 Python
Django自定义全局403、404、500错误页面的示例代码
Mar 08 Python
Python调用.net动态库实现过程解析
Jun 05 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/06/09 PHP
PHP服务器页面间跳转实现方法
2012/08/02 PHP
php使用array_search函数实现数组查找的方法
2015/06/12 PHP
PHP封装的HttpClient类用法实例
2015/06/17 PHP
PHP魔术方法之__call与__callStatic使用方法
2017/07/23 PHP
php5.5使用PHPMailer-5.2发送邮件的完整步骤
2018/10/14 PHP
Laravel登录失败次数限制的实现方法
2020/08/26 PHP
jquery 图片截取工具jquery.imagecropper.js
2010/04/09 Javascript
jquery.validate使用攻略 第一部
2010/07/01 Javascript
js实现仿Discuz文本框弹出层效果
2015/08/13 Javascript
JavaScript function函数种类详解
2016/02/22 Javascript
纯原生js实现贪吃蛇游戏
2020/04/16 Javascript
浅谈关于angularJs中使用$.ajax的注意点
2017/08/12 Javascript
Node.js中环境变量process.env的一些事详解
2017/10/26 Javascript
jQuery ajax读取本地json文件的实例
2017/10/31 jQuery
基于js 字符串indexof与search方法的区别(详解)
2017/12/04 Javascript
学习React中ref的两个demo示例
2018/08/14 Javascript
Vue将页面导出为图片或者PDF
2020/08/17 Javascript
javaScript 实现重复输出给定的字符串的常用方法小结
2020/02/20 Javascript
vue中axios封装使用的完整教程
2021/03/03 Vue.js
python 图片验证码代码
2008/12/07 Python
Windows10+anacond+GPU+pytorch安装详细过程
2020/03/24 Python
日本小田急百货官网:Odakyu
2018/07/19 全球购物
Sarenza德国:法国最大的时尚鞋和包包网上商店
2019/06/08 全球购物
美国领先的宠物用品和宠物食品零售商:Petco
2020/10/28 全球购物
下列程序在32位linux或unix中的结果是什么
2015/01/26 面试题
销售人员中英文自荐信
2013/09/22 职场文书
应届大专毕业生个人自荐信
2013/09/22 职场文书
党员2014两会学习心得体会
2014/03/17 职场文书
新学期开学演讲稿
2014/05/24 职场文书
公司新人试用期自我评价
2014/09/17 职场文书
教师自我剖析材料范文
2014/09/30 职场文书
工作年限证明模板
2014/11/01 职场文书
2014离婚协议书范文(3篇)
2014/11/29 职场文书
农业项目合作意向书
2015/05/08 职场文书
Oracle锁表解决方法的详细记录
2022/06/05 Oracle