设为首页 收藏本站
查看: 2090|回复: 0

[经验分享] 使用Python处理XML

[复制链接]

尚未签到

发表于 2017-4-26 06:02:16 | 显示全部楼层 |阅读模式
  很久没有写博文了,也很久没有碰Python了。刚好工作需要,小小动手了下。
  因为是在新机器上,所以就直接装了Python 3,反正以后也是要适应,不如早点。
  

  在使用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):passdef __call__(self, filepath):retDict = {}f = open(filepath, 'r')Line = len(open(filepath, 'r').readlines())retDict['Line'] = Linetree = etree.parse(f)root = tree.find("ResItem")Id = root.get("ID")retDict['Title'] = IdresItemCnt = len(list(root.findall("ResItem"))) + 1retDict['ResItemCount'] = resItemCntretDict['ChineseTip'] = 'None'for child in root:attrDict = child.attribkeyword = "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'] = realTitlef.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, totalXmlFileCntglobal totalErrorCnt, errorFileListglobal xmlRootfor i in os.listdir(path):if i[-3:] == 'xml':totalXmlFileCnt += 1try:#先把xml的encoding由gb2312转换为utf-8replaceXmlEncoding(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 += 1errorFileList.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()

  

  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-369191-1-1.html 上篇帖子: Perl vs. Python vs. Ruby 下篇帖子: 使用Python操作注册表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表