XML解析 (python)

来源:互联网 发布:ds数据精灵好用吗 编辑:程序博客网 时间:2024/06/08 04:19
XML
   XML是可扩展标记语言(eXtenensible Markup Language)(HTML是超级文本语言)
   XML被设计用来传输和存储数据(HTML用来显示数据)
   XML树结构 (XML的标签是自定义的,HTML标签是规定的)
  1. <?xml version="1.0" encoding="UTF-8"?> #声明
  2. <root> #根元素
  3. <child> #子元素
  4. <subchild>.....</subchild> #子子元素
  5. #<tag attrib>text<tail>
  6. </child>
  7. </root>
python对XML解析
   XML编程常用接口有DOM和SAX
   python有常用三种方法解析XML SAX,DOM,以及ElementTree
   1.SAX(simple API for XML)
       python标准库包含SAX解析器,SAX用事件驱动模型,通过解析XML的过程触发一个个事件并调用用户定义函数来处理XML文件。基于事件回调机制。
       
   2.DOM(Document Object Model)
       将XML数据在内存解析成一个树,通过对树的操作来操作XML
   3.ElementTree(元素树)
       轻量级的DOM,更友好的API.可用性更好,速度快,消耗内存少
   DOM会把整个XML读入内存,解析为树,因此占用内存大,解析慢,优点是可以任意遍历树的节点SAX(优先)是流模式,边读边解析,占用内存小,解析快,缺点是我们需要自己处理事件。

   xml解析模块
   xml.domDOM API 
   xml.dom.minidomDOM API的极简化实现
   xml.dom.pulldom: 'pull解析器',从xml流中pull事件,然后处理,与SAX一样采用事件驱动模型,但pull解析器需使用者明确xml流中pull事件,对时间进行遍历处理,直到结束或错误。
   xml.sax: SAX API
   xml.parser.expat: expat解析器的底层API接口。类似SAX,但只适合expat库。
   xml.etree.ElementTree:轻量级、Pythonic的API.(首选)

ElementTree(ET)解析XML
   ET提供两个对象:
       ElementTree将整个文档转化为树(xml文档交互)
       Element则代表树上节点(单个xml元素及其子元素)

   创建xml示例文件test.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <students>
  3. <student no="2009081097">
  4. <name>Hongten</name>
  5. <gender>M</gender>
  6. <age>20</age>
  7. <score subject="math">97</score>
  8. <score subject="chinese">90</score>
  9. </student>
  10. </students>
   1.xml解析文件导入
  1. #ET模块导入
  2. >>> import xml.etree.ElementTree as ET
  3. #xml文件导入
  4. >>> tree = ET.parse('/root/test.xml')
   2.解析根元素
  1. #根节点获取
  2. >>> root = tree.getroot()
  3. #根元素解析
  4. >>> root = tree.getroot()
  5. >>> print('root.tag=',root.tag)
  6. root.tag= students
  7. >>> print('root.attrib=',root.attrib)
  8. root.attrib= {}
   3.解析根的儿子
  1. >>> for child in root:
  2. ... print(child.tag)
  3. ... print(child.attrib) #字典
  4. ...
  5. student
  6. {'no': '2009081097'}
   4.索引解析根的子孙
  1. >>> print(root[0][0].tag)
  2. name
  3. >>> print(root[0][0].text)
  4. Hongten
  5. >>> print(root[0][4].tag)
  6. score
  7. >>> print(root[0][4].attrib)
  8. {'subject': 'chinese'}
  9. >>> print(root[0][4].text)
  10. 90
   5.迭代器遍历解析出指定的元素
  1. >>> for student in root.iter(tag='student'):
  2. ... print(student.attrib)
  3. ...
  4. {'no': '2009081097'}
   6.其他解析
  1. # element.findall()解析出指定element的所有儿子
  2. # element.find()解析出指定element的第一个儿子
  3. # element.get()解析出指定element的attrib的key对应值
  4. >>> for student in root.findall('student'):
  5. ... score=student.find('score')
  6. ... print(score.tag,score.attrib,score.text)
  7. ... print(score.get('subject'))
  8. ...
  9. score {'subject': 'math'} 97
  10. math
   
SAX解析XML
   SAX是基于事件驱动的API
   SAX解析xml文档分:解析器和事件处理器
       解析器:负责读取xml文档并向时间处理器发送事件。
       事件处理器:负责对事件做出响应,对传递的xml数据进行处理。
           1.大型文件处理;
           2.需文件部分内容;
           3.想建立自己的对象模型。
xml.sax
   parser
   创建一个SAX解析器并解析xml文档
  1. xml.sax.parse( xmlfile, contenthandler[, errorhandler])
  2. xmlfile xml 文件名
  3. contenthandler 必须是一个ContentHandler的对象
  4. errorhandler 如果指定该参数,errorhandler必须是一个SAX ErrorHandler对象
   make_parser
   创建一个新的解析器对象并返回
  1. xml.sax.make_parser( [parser_list] )
  2. parser_list 可选参数,解析器列表
   parseString
   创建一个XML解析器并解析xml字符串
  1. xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
  2. xmlstring xml字符串
  3. contenthandler 必须是一个ContentHandler的对象
  4. errorhandler 如果指定该参数,errorhandler必须是一个SAX ErrorHandler对象

xml.sax.handler
   ContentHandler
  1. characters(content)
  2. 调用时机:
  3. 从行开始,遇到标签之前,存在字符,content的值为这些字符串。
  4. 从一个标签,遇到下一个标签之前, 存在字符,content的值为这些字符串。
  5. 从一个标签,遇到行结束符之前,存在字符,content的值为这些字符串。
  6. 标签可以是开始标签,也可以是结束标签。
  7. startDocument()
  8. 文档启动的时候调用。
  9. endDocument()
  10. 解析器到达文档结尾时调用。
  11. startElement(name, attrs)
  12. 遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典。
  13. endElement(name)
  14. 遇到XML结束标签时调用。
   
   实例文档movies.xml
  1. <collection shelf="New Arrivals">
  2. <movie title="Enemy Behind">
  3. <type>War, Thriller</type>
  4. <year>2003</year>
  5. <description>Talk about a US-Japan war</description>
  6. </movie>
  7. <movie title="Transformers">
  8. <type>Anime, Science Fiction</type>
  9. <year>1989</year>
  10. <description>A schientific fiction</description>
  11. </movie>
  12. </collection>    
   
   xml解析脚本
  1. #!/usr/bin/env python3
  2. # -*- coding: UTF-8 -*-
  3. import xml.sax
  4. class MovieHandler(xml.sax.ContentHandler):
  5. def __init__(self):
  6. self.CurrentData=''
  7. self.type=''
  8. self.year=''
  9. self.description=''
  10. #元素开始事件处理
  11. def startElement(self,tag,attributes):
  12. self.CurrentData=tag
  13. if tag=='movie':
  14. title=attributes['title']
  15. print('Title:',title)
  16. #元素结束事件处理
  17. def endElement(self,tag):
  18. if self.CurrentData=='type':
  19. print('Type:',self.type)
  20. elif self.CurrentData=='year':
  21. print('Year:',self.year)
  22. elif self.CurrentData=='description':
  23. print('Description:',self.description)
  24. self.CurrentData=''
  25. #内容事件处理
  26. def characters(self,content):
  27. if self.CurrentData=='type':
  28. self.type=content
  29. elif self.CurrentData=='year':
  30. self.year=content
  31. elif self.CurrentData=='description':
  32. self.description=content
  33. if __name__=='__main__':
  34. #重写ContextHandler
  35. Handler=MovieHandler()
  36. #创建一个xmlreader
  37. parser=xml.sax.make_parser()
  38.    #setFeature设置解析器功能xml.sax.handler.feature_namespaces是url路径变量
  39.    #没有也能正常解析
  40. parser.setFeature(xml.sax.handler.feature_namespaces,0)
  41.    #关联sax处理器与ContentHandler实例适合内部的start end 内容事件 方法对应
  42. parser.setContentHandler(Handler)
  43. parser.parse('movies.xml')
   结果:
  1. Title: Enemy Behind
  2. Type: War, Thriller
  3. Year: 2003
  4. Description: Talk about a US-Japan war
  5. Title: Transformers
  6. Type: Anime, Science Fiction
  7. Year: 1989
  8. Description: A schientific fiction
学习:http://www.runoob.com/python3/python3-xml-processing.html 
    http://www.liaoxuefeng.com/