• 愉快的体验 Python XML 处理

1. 源代码

   1 # -*- coding: UTF-8 -*-
   2 """modifiles auto check
   3     - 每周CVS 更新文件分析脚本!
   4     - 自动查找本周更新过的文件,计数
   5     - 汇出为XML
   6 @version: $Id: modifiles.py,v 1.3 2004/12/26 14:10:04 zhouqi Exp $
   7 @author: U{Zoom.Quiet<mailto:[email protected]>}
   8 """
   9 import sys,os,string
  10 import time
  11 from elementtree import ElementTree
  12 from elementtree.ElementTree import Element, SubElement, tostring
  13 class modifiles:
  14     """主类,集成所有处理
  15     """
  16     def __init__(self):
  17         """初始化参数
  18         """
  19         self.xml = "/home/zoomq/share/statcvs/weeklystat.xml"
  20         self.xmlhead = """<?xml version="1.0" encoding="UTF-8"?>
  21 <!-- edited with elementtree (http://effbot.org/zone/element-index.htm) by Zoom.Quiet  -->
  22 <?xml-stylesheet type="text/xsl" href="statcvs.xsl"?>
  23         """
  24         self.cvsroot = "/cvs/root/"
  25         self.finder = "find %s -mtime -7 -type f | wc -l | awk '{print $1}'"
  26         self.report = {}
  27         self.cvs = ("scm"
  28             ,"MTA"
  29             ,"sinaInterface"
  30             ,"sina668"
  31             ,"sinasys"
  32             ,"webmail"
  33             ,"runmanage"
  34             ,"sinaIndex")
  35 
  36     def checking(self):
  37         """逐一处理所有模块
  38         """
  39         os.chdir(self.cvsroot)
  40         for key in self.cvs:
  41             os.chdir(self.cvsroot+key)
  42             re = os.popen(self.finder%(self.cvsroot+key))
  43             sre = re.read()
  44             self.report[key] = sre[:-1]
  45         self.put2xml()
  46     def put2xml(self):
  47         """汇出数据为XML文件!
  48             - 使用轻型XML操作库 Elements and Element Trees
  49             - @see: U{Elements<http://effbot.org/zone/element.htm>}
  50         """
  51         zday = time.strftime("%Y-%m-%d",time.localtime(time.time()))
  52         tree = ElementTree.parse(self.xml).getroot()
  53         week = tree.findall("week")
  54         # 先判定是否要记录
  55         done = 0
  56         for node in week:
  57             if(zday==node.attrib["date"]):
  58                   done = 1
  59                   break
  60             cvs = node.findall("cvs")
  61         if(0==done):
  62             print "need recording...will exp. as xml file"
  63             neweek = Element("week")
  64             neweek.set("date", zday)
  65             statcount = 0
  66             for proj in self.report:
  67                 newcvs = SubElement(neweek, "cvs")
  68                 newcvs.set("name", proj)
  69                 statcount +=int(self.report[proj])
  70                 newcvs.set("modifiles", self.report[proj])
  71                 newcvs.set("commit", "null")
  72             neweek.set("modifiles", str(statcount))
  73             tree.append(neweek)
  74         else:
  75             print "recorded ...xml file not edit!"
  76             return
  77         #ElementTree.ElementTree(tree).write("out.xml")
  78         code = tostring(tree)
  79         open(self.xml,"w").write(self.xmlhead+code)
  80 if __name__ == '__main__':
  81     """基本运行模式
  82     """
  83     week = modifiles()
  84     week.checking()

2. 编写过程

2.1. 八股文般的开始

  •    1 # -*- coding: UTF-8 -*-
       2 """modifiles auto check
       3     - 每周CVS 更新文件分析脚本!
       4 """
       5 import sys,os,string  # 文件处理什么的总是要的几个包
       6 import time           # 时间处理总是要的
       7 class modifiles:
       8     """主类,集成所有处理
       9     """
      10     def __init__(self):
      11         """初始化参数
      12         """
      13         self.cvsroot = "/cvs/root/"
      14         return
      15     def checking(self):
      16         """逐一处理所有模块
      17         """
      18         os.chdir(self.cvsroot)
      19         for key in self.cvs:
      20             os.chdir(self.cvsroot+key)
      21             #开始针对每一CVS 进行搜索            
      22         #self.put2xml()
      23         #最后尝试XML输出
      24 if __name__ == '__main__':
      25     """基本运行模式
      26     """
      27     week = modifiles()
      28     week.checking()
    
  • 基本上每一小应用我都是这样开始的,
    • 使用 class 组织
    • 首先确定自运行模式,以此为标准来展开实际行为的填写
    • 先将所有函式放空,一点点来编写,
    • 保证,每一次行为的增加都有正确的运行结果,
    • 保持成就感!绝对不制造惊奇!

2.2. 收集必要参数

  •    1   ...
       2         self.cvsroot = "/cvs/root/"
       3         self.finder = "find %s -mtime -7 -type f | wc -l | awk '{print $1}'"
       4         self.report = {}
       5         self.cvs = ("scm"
       6             ,"MTA"
       7             ,"sinaInterface"
       8             ,"sina668"
       9             ,"sinasys"
      10             ,"webmail"
      11             ,"runmanage"
      12             ,"sinaIndex")
    
  • 配合的行为函式是:
  •    1     def checking(self):
       2         """逐一处理所有模块
       3         """
       4         os.chdir(self.cvsroot)
       5         for key in self.cvs:
       6             os.chdir(self.cvsroot+key)
       7             #进入对应目录
       8             re = os.popen(self.finder%(self.cvsroot+key))
       9             # 进行查找
      10             sre = re.read()
      11             # 汇入数据对象
      12             self.report[key] = sre[:-1]
      13         #self.put2xml()
    
  • 非常直观,和简单!
  • 注意的是:

    • os.popen() 返回系统命令运行结果为一个临时的 file 对象,如果当时不将内容读取的话,马上就会被自动清空!

2.3. XML汇出

  • ElementTree 的文档组织的一般,没有象 ADOdb 那样完整的典型示范代码,

  • 不过在 Python 脚本中只要随时随地的运行观察结果就可以快速印证自个儿的理解来完成开发
  •    1 from elementtree import ElementTree
       2 from elementtree.ElementTree import Element, SubElement, tostring
       3 ...
    

    -- 引入 ElementTree 对象

  • 实际仅仅利用了几个行为,就完成任务!
    1. 读取XML初始化DOM树
    2. 使用XPath 搜索获得结点集合
      • week = tree.findall("week")

    3. 创立新的 ElementTree XML dom 结点

      • neweek = Element("week")

    4. 对结点对象设置属性
      • neweek.set("date", zday)

    5. 为XML dom 结点对象 创建子结点
      • newcvs = Sub Element(neweek, "cvs")

    6. 向结点对象追加XML dom 对象结点
      • tree.append(neweek)

  • 注意的是:

    • ElementTree.ElementTree(tree).write("out.xml")

    • ElementTree 自个儿的XML 回写还不完善,对编码什么的支持不好,

    • 所以,简直的使用变通方式就完成之:
      • open(self.xml,"w").write(self.xmlhead+code)

3. ElementTree