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操作的在线工具供大家参考使用:
在线