最近迷恋上了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:])