这里的操作是基于Python3平台。
在使用Python处理XML的问题上,首先遇到的是编码问题。
Python并不支持gb2312,所以面对encoding="gb2312"的XML文件会出现错误。Python读取的文件本身的编码也可能导致抛出异常,这种情况下打开文件的时候就需要指定编码。此外就是XML中节点所包含的中文。
我这里呢,处理就比较简单了,只需要修改XML的encoding头部。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#!/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__函数用来测试真是蛮好用的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#!/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错误挺有意思的,不知道是不是符号表的覆盖问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
#!/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程序设计有所帮助。