设为首页 收藏本站
查看: 602|回复: 0

[经验分享] python网络编程学习笔记(8):XML生成与解析(DOM、ElementTree)

[复制链接]

尚未签到

发表于 2015-4-23 06:10:55 | 显示全部楼层 |阅读模式
  转载请注明:@小五义http://www.iyunv.com/xiaowuyi
  xml.dom篇
      DOM是Document Object Model的简称,XML 文档的高级树型表示。该模型并非只针对 Python,而是一种普通XML 模型。Python 的 DOM 包是基于 SAX 构建的,并且包括在 Python 2.0 的标准 XML 支持里。

一、xml.dom的简单介绍
  1、主要方法:
  minidom.parse(filename):加载读取XML文件
  doc.documentElement:获取XML文档对象
  node.getAttribute(AttributeName):获取XML节点属性值
  node.getElementsByTagName(TagName):获取XML节点对象集合
  node.childNodes :返回子节点列表。
  node.childNodes[index].nodeValue:获取XML节点值
  node.firstChild:访问第一个节点,等价于pagexml.childNodes[0]
  返回Node节点的xml表示的文本:
  doc = minidom.parse(filename)
  doc.toxml('UTF-8')
  访问元素属性:
  Node.attributes["id"]
a.name #就是上面的 "id"
a.value #属性的值  
2、举例说明
  例1:文件名:book.xml





Book message

bookone
python check
001
200


booktwo
python learn
002
300


  
  (1)创建DOM对象



import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
  
  (2)获取根字节
  root=dom1.documentElement #这里得到的是根节点
print root.nodeName,',',root.nodeValue,',',root.nodeType
  返回结果为:
  info , None , 1
  其中:
  info是指根节点的名称root.nodeName
  None是指根节点的值root.nodeValue
  1是指根节点的类型root.nodeType,更多节点类型如下表:
  



  NodeType

  Named Constant

  1

  ELEMENT_NODE

  2

  ATTRIBUTE_NODE

  3

  TEXT_NODE

  4

  CDATA_SECTION_NODE

  5

  ENTITY_REFERENCE_NODE

  6

  ENTITY_NODE

  7

  PROCESSING_INSTRUCTION_NODE

  8

  COMMENT_NODE

  9

  DOCUMENT_NODE

  10

  DOCUMENT_TYPE_NODE

  11

  DOCUMENT_FRAGMENT_NODE

  12

  NOTATION_NODE

  (3)子元素、子节点的访问
  A、返回root子节点列表



import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentElement
#print root.nodeName,',',root.nodeValue,',',root.nodeType
print root.childNodes
  运行结果为:
  [, , , , , , ]
  B、获取XML节点值,如返回根节点下第二个子节点intro的值和名字,添加下面一句



print root.childNodes[1].nodeName,root.childNodes[1].nodeValue
  
  运行结果为:
  intro None
  C、访问第一个节点



print root.firstChild.nodeName
  运行结果为:
  #text
  D、获取已经知道的元素名字的值,如要获取intro后的book message可以使用下面的方法:



import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentElement
#print root.nodeName,',',root.nodeValue,',',root.nodeType
node= root.getElementsByTagName('intro')[0]
for node in node.childNodes:
if node.nodeType in (node.TEXT_NODE,node.CDATA_SECTION_NODE):
print node.data
  
  这种方法的不足之处是需要对类型进行判断,使用起来不是很方便。运行结果是:
  Book message

二、XML解析
  对上面的xml进行解析
  方法1 代码如下:



#@小五义 http://www.iyunv.com/xiaowuyi
#xml 解析
import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentElement
book={}
booknode=root.getElementsByTagName('list')
for booklist in booknode:
print '='*20
print 'id:'+booklist.getAttribute('id')
for nodelist in  booklist.childNodes:
if nodelist.nodeType ==1:
print nodelist.nodeName+':',
for node in nodelist.childNodes:
print node.data
  运行结果为:
  ====================
id:001
head: bookone
name: python check
number: 001
page: 200
====================
id:002
head: booktwo
name: python learn
number: 002
page: 300
  方法二:
  代码:



#@小五义 http://www.iyunv.com/xiaowuyi
#xml 解析
import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentElement
book={}
booknode=root.getElementsByTagName('list')
for booklist in booknode:
print '='*20
print 'id:'+booklist.getAttribute('id')
print 'head:'+booklist.getElementsByTagName('head')[0].childNodes[0].nodeValue.strip()
print 'name:'+booklist.getElementsByTagName('name')[0].childNodes[0].nodeValue.strip()
print 'number:'+booklist.getElementsByTagName('number')[0].childNodes[0].nodeValue.strip()
print 'page:'+booklist.getElementsByTagName('page')[0].childNodes[0].nodeValue.strip()
  运行结果与方法一一样。比较上面的两个方法,方法一根据xml的树结构进行了多次循环,可读性上不及方法二,方法直接对每一个节点进行操作,更加清晰。为了更加方法程序的调用,可以使用一个list加一个字典进行存储,具体见方法3:



#@小五义 http://www.iyunv.com/xiaowuyi
#xml 解析
  import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentElement
book=[]
booknode=root.getElementsByTagName('list')
for booklist in booknode:
    bookdict={}
    bookdict['id']=booklist.getAttribute('id')
    bookdict['head']=booklist.getElementsByTagName('head')[0].childNodes[0].nodeValue.strip()
    bookdict['name']=booklist.getElementsByTagName('name')[0].childNodes[0].nodeValue.strip()
    bookdict['number']=booklist.getElementsByTagName('number')[0].childNodes[0].nodeValue.strip()
    bookdict['page']=booklist.getElementsByTagName('page')[0].childNodes[0].nodeValue.strip()
    book.append(bookdict)
print book
  运行结果为:
  [{'head': u'bookone', 'page': u'200', 'number': u'001', 'id': u'001', 'name': u'python check'}, {'head': u'booktwo', 'page': u'300', 'number': u'002', 'id': u'002', 'name': u'python learn'}]
  该列表里包含了两个字典。

三、建立XML文件
  这里用方法三得到的结果,建立一个xml文件。



# -*- coding: cp936 -*-
#@小五义 http://www.iyunv.com/xiaowuyi
#xml 创建
import xml.dom
def create_element(doc,tag,attr):
#创建一个元素节点
elementNode=doc.createElement(tag)
#创建一个文本节点
textNode=doc.createTextNode(attr)
#将文本节点作为元素节点的子节点
    elementNode.appendChild(textNode)
return elementNode
dom1=xml.dom.getDOMImplementation()#创建文档对象,文档对象用于创建各种节点。
doc=dom1.createDocument(None,"info",None)
top_element = doc.documentElement# 得到根节点
books=[{'head': u'bookone', 'page': u'200', 'number': u'001', 'id': u'001', 'name': u'python check'}, {'head': u'booktwo', 'page': u'300', 'number': u'002', 'id': u'002', 'name': u'python learn'}]
for book in books:
sNode=doc.createElement('list')
sNode.setAttribute('id',str(book['id']))
headNode=create_element(doc,'head',book['head'])
nameNode=create_element(doc,'name',book['name'])
numberNode=create_element(doc,'number',book['number'])
pageNode=create_element(doc,'page',book['page'])
sNode.appendChild(headNode)
sNode.appendChild(nameNode)
sNode.appendChild(pageNode)
top_element.appendChild(sNode)# 将遍历的节点添加到根节点下
xmlfile=open('bookdate.xml','w')
doc.writexml(xmlfile,addindent=' '*4, newl='\n', encoding='utf-8')
xmlfile.close()
  运行后生成bookdate.xml文件,该文件与book.xml一样。
  xml.etree.ElementTree篇
  依然使用例1的例子,对xml进行解析分析。
  1、加载XML
  方法一:直接加载文件



import xml.etree.ElementTree
root=xml.etree.ElementTree.parse('book.xml')
  方法二:加载指定字符串



import xml.etree.ElementTree
root = xml.etree.ElementTree.fromstring(xmltext)
  这里xmltext是指定的字符串。
  2、获取节点
  方法一 利用getiterator方法得到指定节点



book_node=root.getiterator("list")
  方法二 利用getchildren方法得到子节点,如例1中,要得到list下面子节点head的值:



#@小五义 http://www.iyunv.com/xiaowuyi
import xml.etree.ElementTree
root=xml.etree.ElementTree.parse('book.xml')
book_node=root.getiterator("list")
for node in book_node:
book_node_child=node.getchildren()[0]
print book_node_child.tag+':'+book_node_child.text
  运行结果为:
  head:bookone
head:booktwo
  方法三 使用find和findall方法
  find方法找到指定的第一个节点:



# -*- coding: cp936 -*-
#@小五义 http://www.iyunv.com/xiaowuyi
import xml.etree.ElementTree
root=xml.etree.ElementTree.parse('book.xml')
book_find=root.find('list')
for note in book_find:
print note.tag+':'+note.text
  
  运行结果:
  head:bookone
name:python check
number:001
page:200
  findall方法将找到指定的所有节点:



# -*- coding: cp936 -*-
#@小五义 http://www.iyunv.com/xiaowuyi
import xml.etree.ElementTree
root=xml.etree.ElementTree.parse('book.xml')
book=root.findall('list')
for book_list in book:
for note in book_list:
print note.tag+':'+note.text
  
  运行结果:
  head:bookone
name:python check
number:001
page:200
head:booktwo
name:python learn
number:002
page:300
  3、对book.xml进行解析的实例



# -*- coding: cp936 -*-
#@小五义 http://www.iyunv.com/xiaowuyi
import xml.etree.ElementTree
root=xml.etree.ElementTree.parse('book.xml')
book=root.findall('list')
for book_list in book:
print '='*20
if  book_list.attrib.has_key('id'):
print "id:"+book_list.attrib['id']
for note in book_list:
print note.tag+':'+note.text
print '='*20
  
  运行结果为:
  ====================
id:001
head:bookone
name:python check
number:001
page:200
====================
id:002
head:booktwo
name:python learn
number:002
page:300
====================
  
  注意:
  当要获取属性值时,如list id=’001’,用attrib方法。
  当要获取节点值时,如bookone中的bookone用text方法。
  当要获取节点名时,用tag方法。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-59706-1-1.html 上篇帖子: python类的成员和装饰器 下篇帖子: python开发_function annotations
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表