Python处理XML格式数据的方法详解
本文实例讲述了Python处理XML格式数据的方法。分享给大家供大家参考,具体如下:
这里的操作是基于Python3平台。
在使用Python处理XML的问题上,首先遇到的是编码问题。
Python并不支持gb2312,所以面对encoding="gb2312"的XML文件会出现错误。Python读取的文件本身的编码也可能导致抛出异常,这种情况下打开文件的时候就需要指定编码。此外就是XML中节点所包含的中文。
我这里呢,处理就比较简单了,只需要修改XML的encoding头部。
#!/usr/bin/envpython importos,sys importre defreplaceXmlEncoding(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/envpython importos,re importxml.etree.ElementTreeasetree Locale_Path="./locale.txt" classxmlExtractor(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' forchildinroot: attrDict=child.attrib keyword="Name" if(keywordinattrDict.keys()andattrDict['Name']=="Caption"): iflen(child.attrib['Value'])>1: ifchild.attrib['Value'][0]=='~': title=child.attrib['Value'][1:] else: title=child.attrib['Value'][0:] #print(title) chs=open(Locale_Path).read() pattern='[^>]+>' m=re.search(pattern,chs) ifm!=None: realTitle=re.sub('<[^>]+>','',m.group(0)) retDict['ChineseTip']=realTitle f.close() returnretDict if__name__=="__main__": fo=xmlExtractor() d=fo('./ActivateAccount.xml') print(d)
最后,就是入口文件,导入上面两个文件,使用xml.dom和os.listdir来递归处理XML文件,并生成一个结果集。
一直觉得Python的UnboundLocalError错误挺有意思的,不知道是不是符号表的覆盖问题。
#!/usr/bin/envpython fromxmlExtractorimport* fromreplaceXmlEncodingimport* fromxml.domimportminidom,Node doc=minidom.Document() extractor=xmlExtractor() totalLines=0 totalResItemCnt=0 totalXmlFileCnt=0 totalErrorCnt=0 errorFileList=[] xmlRoot=doc.createElement("XmlResourceFile") doc.appendChild(xmlRoot) defmyWalkDir(level,path): globaldoc,extractor,totalLines,totalResItemCnt,totalXmlFileCnt globaltotalErrorCnt,errorFileList globalxmlRoot foriinos.listdir(path): ifi[-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) exceptExceptionaserrorDetail: totalErrorCnt+=1 errorFileList.append(path+'\\'+i) print(path+'\\'+i,errorDetail) ifos.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操作的在线工具供大家参考使用:
在线