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脚本实现查找webshell的方法
Jul 31 Python
Python解析树及树的遍历
Feb 03 Python
关于pip的安装,更新,卸载模块以及使用方法(详解)
May 19 Python
Python自动化运维_文件内容差异对比分析
Dec 13 Python
Python后台开发Django会话控制的实现
Apr 15 Python
python如何获取列表中每个元素的下标位置
Jul 01 Python
Python使用百度api做人脸对比的方法
Aug 28 Python
python图片指定区域替换img.paste函数的使用
Apr 09 Python
python实现粒子群算法
Oct 15 Python
详解利用python识别图片中的条码(pyzbar)及条码图片矫正和增强
Nov 17 Python
Jupyter notebook 更改文件打开的默认路径操作
May 21 Python
python读取mnist数据集方法案例详解
Sep 04 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
wampserver改变默认网站目录的办法
2015/08/05 PHP
PHP面向对象五大原则之开放-封闭原则(OCP)详解
2018/04/04 PHP
分享5个非常有用的Laravel Blade指令
2018/05/30 PHP
ThinkPHP5框架中使用JWT的方法示例
2020/06/03 PHP
THREE.JS入门教程(3)着色器-下
2013/01/24 Javascript
jquery如何判断表格同一列不同行input数据是否重复
2014/05/14 Javascript
JQuery悬停控制图片轮播——代码简单
2015/08/05 Javascript
js如何判断访问是来自搜索引擎(蜘蛛人)还是直接访问
2015/09/14 Javascript
Node.js操作mysql数据库增删改查
2016/03/30 Javascript
DIV随滚动条滚动而滚动的实现代码【推荐】
2016/04/12 Javascript
JavaScript基础教程——入门必看篇
2016/05/20 Javascript
Jquery实现select multiple左右添加和删除功能的简单实例
2016/05/26 Javascript
JavaScript数组方法大全(推荐)
2016/07/05 Javascript
浅谈jQuery中的checkbox问题
2016/08/10 Javascript
D3.js实现柱状图的方法详解
2016/09/21 Javascript
JavaScript中日常收集常见的10种错误(推荐)
2017/01/08 Javascript
基于jQuery的$.getScript方法去加载javaScript文档解析
2017/11/08 jQuery
详解Eslint 配置及规则说明
2018/09/10 Javascript
vue动态删除从数据库倒入列表的某一条方法
2018/09/29 Javascript
JavaScript中0、空字符串、'0'是true还是false的知识点分享
2019/09/16 Javascript
原生js无缝轮播插件使用详解
2020/03/09 Javascript
[48:35]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 TNC vs Optic
2018/04/03 DOTA
[42:34]VP vs VG 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
Python写的一个简单DNS服务器实例
2014/06/04 Python
python使用calendar输出指定年份全年日历的方法
2015/04/04 Python
Python+pyplot绘制带文本标注的柱状图方法
2019/07/08 Python
python 通过邮件控制实现远程控制电脑操作
2020/03/16 Python
python接入支付宝的实例操作
2020/07/20 Python
python实现控制台输出颜色
2021/03/02 Python
Pytorch之扩充tensor的操作
2021/03/04 Python
英国家具、照明、家居用品网上商店:Wayfair.co.uk
2020/02/13 全球购物
心理健康心得体会
2014/01/02 职场文书
监察建议书格式
2014/05/19 职场文书
实习证明格式范文
2015/06/16 职场文书
2016年教师节特级教师获奖感言
2015/12/09 职场文书
2016年教师师德师风心得体会
2016/01/12 职场文书