侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

Python  /  管理员 发布于 7年前   259

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

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

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

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

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

#!/usr/bin/env pythonimport os, sysimport redef 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 pythonimport os, reimport xml.etree.ElementTree as etreeLocale_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 retDictif __name__ == "__main__":  fo = xmlExtractor()  d = fo('./ActivateAccount.xml')  print(d)

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

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

#!/usr/bin/env pythonfrom xmlExtractor import *from replaceXmlEncoding import *from xml.dom import minidom,Nodedoc = minidom.Document()extractor = xmlExtractor()totalLines = 0totalResItemCnt = 0totalXmlFileCnt = 0totalErrorCnt = 0errorFileList = []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()

PS:这里再为大家提供几款关于xml操作的在线工具供大家参考使用:

在线XML/JSON互相转换工具:
http://tools..net.cn/code/xmljson

在线格式化XML/在线压缩XML:
http://tools..net.cn/code/xmlformat

XML在线压缩/格式化工具:
http://tools..net.cn/code/xml_format_compress

XML代码在线格式化美化工具:
http://tools..net.cn/code/xmlcodeformat

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python操作xml数据技巧总结》、《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。


  • 上一条:
    Python正则简单实例分析
    下一条:
    Python做简单的字符串匹配详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中实现字符串可逆性压缩及解压缩功能(0个评论)
    • 使用go + gin + jwt + qrcode实现网站生成登录二维码在app中扫码登录功能(0个评论)
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客