python学习(一) 如何解析xml文件

最近迷恋上了python,因为脚本语言确实很强大,之前写的perl代码现在基本都看不明白了,因此果断放弃perl,投身python怀抱。

学习的一个好办法就是自己找问题,然后coding解问题。因此我给自己出了道题。

即android source code是由若干个git project组成的,其中有一个manifest.xml统一管理这些project,用repo命令可以很方便的管理操作这些project。如果想知道当前source code的所有project的commit号,通过下面命令可以获取

repo manifest -r -o manifest_xx.xml

其中这个manifest_xx.xml里含有所有project当前的commit信息。

假如有两个这样的manifest.xml,我们想提取其中的name, path及revision信息,来判断究竟哪些project有更新,后续可以根据这些获取的信息来做两个版本的delta patch。

因此一个关键点是如何通过python解析xml?

这里先共享一个好网站 http://docs.python.org/2.7/library/xml.etree.elementtree.html 里面的例子通熟易懂,教你如何使用python解析xml。

贴上我写好的python,python的一个优势就是容易读懂。这里主要两个知识点,一个是如何解析XML,一个是如何使用字典。

#!/usr/bin/python
import getopt
import pickle
import subprocess
import sys
import xml.etree.ElementTree as ET

def dump_dict(_dict):
	i = 0;
	for key in _dict.keys():
		i += 1
		print '[%d] %s:  %s' % (i, key, _dict[key])

def parse_xml(_dict, xml_file):
	tree = ET.parse(xml_file)
	root = tree.getroot()
	for project in root.findall('project'):
		name = project.get('name')
		revision = project.get('revision')
		path = project.get('path')
		if path is None:
			_dict[name] = revision
		else:
			_dict[path] = revision

#	dump_dict(_dict)

def main(argv):
	i = 0
	dict_before = {}
	dict_after = {}
	parse_xml(dict_before, 'manifest_before.xml')
	parse_xml(dict_after, 'manifest_after.xml')
#	if cmp(dict1, dict2) > 0:
#		print 'dict1 > dict2'
#	else:
#		print 'dict1 < dict2'
	for key in dict_before.keys():
		if dict_after.has_key(key):
			i += 1
			print '[%d ]%s: %s: %s' % (i, key, dict_before[key], dict_after[key])

if __name__ == "__main__": 
	main(sys.argv[1:])


当然如果用正则表达式也能完成上述功能,相应代码如下:

#!/usr/bin/python
import re
import sys 
import getopt
import subprocess

before_dict = {}
after_dict = {}
def parse_before_xml(xml_file):
	filp = open(xml_file, 'r')
	for s in filp:
		name = re.findall(r'name=(.+?) ', s)
		version = re.findall(r'revision=(.+?) ', s) 
		before_dict[name[0]] = version[0]
	filp.close()

def parse_after_xml(xml_file):
	filp = open(xml_file, 'r')
	for s in filp:
		name = re.findall(r'name=(.+?) ', s)
		version = re.findall(r'revision=(.+?) ', s) 
		after_dict[name[0]] = version[0]
	filp.close()

def usage():
	print "\techo_file [-b] <before manifest xml file> [-a] <after manifest xml file> "

def main(argv):
	try:
		opts, args = getopt.getopt(argv, "b:a:h")
	except getopt.GetoptError:
		usage()
		sys.exit(2)
	for opt, arg in opts:
		if opt in ("-h"):
			usage()
			sys.exit()
		elif opt in ("-b"):
			before_xml = arg
		elif opt in ("-a"):
			after_xml = arg

	parse_before_xml(before_xml)
	parse_after_xml(after_xml)
	for key in before_dict:
		if before_dict[key] != after_dict[key]:
			print key

if __name__ == "__main__":
	main(sys.argv[1:])


 

 

 

你可能感兴趣的:(python)