Python对xml的操作

来源:互联网 发布:如何设置监控网络连接 编辑:程序博客网 时间:2024/06/05 19:33

一、什么是xml?

xml即可扩展标记语言,它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。

abc.xml

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>
<catalog>
    <maxid>4</maxid>
    <login username="pytest" passwd='123456'>
        <caption>Python</caption>
        <item id="4">
            <caption>测试</caption>
        </item>
    </login>
    <item id="2">
        <caption>Zope</caption>
    </item>
</catalog>

Ok ,从结构上,它很像我们常见的HTML超文本标记语言。但他们被设计的目的是不同的,超文本标记语言被设计用来显示数据,其焦点是数据的外观。它被设计用来传输和存储数据,其焦点是数据的内容。

那么它有如下特征:

首先,它是有标签对组成,<aa></aa>

标签可以有属性:<aa id='123'></aa>

标签对可以嵌入数据:<aa>abc</aa>

标签可以嵌入子标签(具有层级关系):

二、获得标签属性

那么,下面来介绍如何用python来读取这种类型的文件。

复制代码 代码如下:

#coding=utf-8
import  xml.dom.minidom

#打开xml文档
dom = xml.dom.minidom.parse('abc.xml')

#得到文档元素对象
root = dom.documentElement
print root.nodeName
print root.nodeValue
print root.nodeType
print root.ELEMENT_NODE

mxl.dom.minidom 模块被用来处理xml文件,所以要先引入。

xml.dom.minidom.parse() 用于打开一个xml文件,并将这个文件对象dom变量。

documentElement 用于得到dom对象的文档元素,并把获得的对象给root

每一个结点都有它的nodeName,nodeValue,nodeType属性。

nodeName为结点名字。

nodeValue是结点的值,只对文本结点有效。

nodeType是结点的类型。catalog是ELEMENT_NODE类型

现在有以下几种:

'ATTRIBUTE_NODE'
'CDATA_SECTION_NODE'
'COMMENT_NODE'
'DOCUMENT_FRAGMENT_NODE'
'DOCUMENT_NODE'
'DOCUMENT_TYPE_NODE'
'ELEMENT_NODE'
'ENTITY_NODE'
'ENTITY_REFERENCE_NODE'
'NOTATION_NODE'
'PROCESSING_INSTRUCTION_NODE'
'TEXT_NODE'


三、获得子标签

现在要获得catalog的子标签以的标签name

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>
<catalog>
       <maxid>4</maxid>
       <login username="pytest" passwd='123456'>
              <caption>Python</caption>
             <item id="4">
                    <caption>测试</caption>
            </item>
    </login>
    <item id="2">
            <caption>Zope</caption>
    </item>
</catalog>

对于知道元素名字的子元素,可以使用getElementsByTagName方法获取:

复制代码 代码如下:

#coding=utf-8
import  xml.dom.minidom

#打开xml文档
dom = xml.dom.minidom.parse('abc.xml')

#得到文档元素对象
root = dom.documentElement

bb = root.getElementsByTagName('maxid')
b= bb[0]
print b.nodeName

bb = root.getElementsByTagName('login')
b= bb[0]
print b.nodeName

如何区分相同标签名字的标签:

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>
<catalog>
       <maxid>4</maxid>
       <login username="pytest" passwd='123456'>
              <caption>Python</caption>
             <item id="4">
                    <caption>测试</caption>
            </item>
    </login>
    <item id="2">
            <caption>Zope</caption>
    </item>
</catalog>

<caption>和<item>标签不止一个如何区分?

复制代码 代码如下:

#coding=utf-8
import  xml.dom.minidom

#打开xml文档
dom = xml.dom.minidom.parse('abc.xml')

#得到文档元素对象
root = dom.documentElement

bb = root.getElementsByTagName('caption')
b= bb[2]
print b.nodeName

bb = root.getElementsByTagName('item')
b= bb[1]
print b.nodeName

root.getElementsByTagName('caption') 获得的是标签为caption 一组标签,b[0]表示一组标签中的第一个;b[2] ,表示这一组标签中的第三个。

四、获得标签属性值

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>
<catalog>
       <maxid>4</maxid>
       <login username="pytest" passwd='123456'>
              <caption>Python</caption>
             <item id="4">
                    <caption>测试</caption>
            </item>
    </login>
    <item id="2">
            <caption>Zope</caption>
    </item>
</catalog>

<login>和<item>标签是有属性的,如何获得他们的属性?

复制代码 代码如下:

#coding=utf-8
import  xml.dom.minidom

#打开xml文档
dom = xml.dom.minidom.parse('abc.xml')

#得到文档元素对象
root = dom.documentElement

itemlist = root.getElementsByTagName('login')
item = itemlist[0]
un=item.getAttribute("username")
print un
pd=item.getAttribute("passwd")
print pd

ii = root.getElementsByTagName('item')
i1 = ii[0]
i=i1.getAttribute("id")
print i

i2 = ii[1]
i=i2.getAttribute("id")
print i

getAttribute方法可以获得元素的属性所对应的值。

五、获得标签对之间的数据

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>
<catalog>
       <maxid>4</maxid>
       <login username="pytest" passwd='123456'>
              <caption>Python</caption>
             <item id="4">
                    <caption>测试</caption>
            </item>
    </login>
    <item id="2">
            <caption>Zope</caption>
    </item>
</catalog>

<caption>标签对之间是有数据的,如何获得这些数据?

获得标签对之间的数据有多种方法,

方法一:

复制代码 代码如下:

#coding=utf-8
import  xml.dom.minidom

#打开xml文档
dom = xml.dom.minidom.parse('abc.xml')

#得到文档元素对象
root = dom.documentElement

cc=dom.getElementsByTagName('caption')
c1=cc[0]
print c1.firstChild.data

c2=cc[1]
print c2.firstChild.data

c3=cc[2]
print c3.firstChild.data

firstChild 属性返回被选节点的第一个子节点,.data表示获取该节点人数据。

方法二:

复制代码 代码如下:

#coding=utf-8
from xml.etree import ElementTree as ET
per=ET.parse('abc.xml')
p=per.findall('./login/item')

for oneper in p:
    for child in oneper.getchildren():
        print child.tag,':',child.text


p=per.findall('./item')

for oneper in p:
    for child in oneper.getchildren():
        print child.tag,':',child.text

方法二有点复杂,所引用模块也与前面的不一样,findall用于指定在哪一级标签下开始遍历。

getchildren方法按照文档顺序返回所有子标签。并输出标签名(child.tag)和标签的数据(child.text)

其实,方法二的作用不在于此,它核心功能是可以遍历某一级标签下的所有子标签。




使用python自带的xml.dom创建和解析xml

    python中的xml.dom模块使用的就是传统的dom解析api和方法。所以也就不写什么了,主要就是练习敲敲代码,继续熟悉python。本文通过xml.dom.minidom创建一个xml文档,然后再解析出来,用以熟悉相关接口方法的使用。

创建一个xml文档:

'''
Created on 2012-1-10
Create a xml document
@author: xiaojay
'''
 
from xml.dom import minidom
 
doc =minidom.Document()
doc.appendChild(doc.createComment("This is a simple xml."))
booklist = doc.createElement("booklist")
doc.appendChild(booklist)
 
def addBook(newbook):
    book= doc.createElement("book")
    book.setAttribute("id", newbook["id"])
     
    title= doc.createElement("title")
    title.appendChild(doc.createTextNode(newbook["title"]))
    book.appendChild(title)
     
    author= doc.createElement("author")
    name= doc.createElement("name")
    firstname= doc.createElement("firstname")
    firstname.appendChild(doc.createTextNode(newbook["firstname"]))
    lastname= doc.createElement("lastname")
    lastname.appendChild(doc.createTextNode(newbook["lastname"]))
    name.appendChild(firstname)
    name.appendChild(lastname)
    author.appendChild(name)
    book.appendChild(author)
     
    pubdate= doc.createElement("pubdate")
    pubdate.appendChild(doc.createTextNode(newbook["pubdate"]))
    book.appendChild(pubdate)
     
    booklist.appendChild(book)
 
addBook({"id":"1001","title":"An apple","firstname":"Peter","lastname":"Zhang","pubdate":"2012-1-12"})
addBook({"id":"1002","title":"Love","firstname":"Mike","lastname":"Li","pubdate":"2012-1-10"})
addBook({"id":"1003","title":"Steve.Jobs","firstname":"Tom","lastname":"Wang","pubdate":"2012-1-19"})
addBook({"id":"1004","title":"Harry Potter","firstname":"Peter","lastname":"Chen","pubdate":"2012-11-11"})
 
f =file("book.xml","w")
doc.writexml(f)
f.close()

  通过doc.toprettyxml(indent, newl, encoding)方法可以优雅显示xml文档,但是要避免直接写入文本,否则会给解析带来麻烦,尽量使用自带的writexml方法。

生成的文档内容:

<?xml version="1.0" ?>
<!--This is a simple xml.-->
<booklist>
  <book id="1001">
    <title>
    An apple
    </title>
  <author>
    <name>
      <firstname>
      Peter
      </firstname>
      <lastname>
      Zhang
      </lastname>
    </name>
  </author>
  <pubdate>
  2012-1-12
  </pubdate>
  </book>

 .................
</booklist>

 

解析该xml文档:

'''
Created on 2012-1-10
Scan a xml doc
@author: xiaojay
'''
 
from xml.dom import minidom , Node
 
class bookscanner:
    def__init__(self,doc):
        forchild in doc.childNodes :
            ifchild.nodeType ==Node.ELEMENT_NODE \
            andchild.tagName =="book" :
                bookid= child.getAttribute("id")
                print"*"*20
                print"Book id : " , bookid
                self.handle_book(child)
                 
    defhandle_book(self,node):
        forchild in node.childNodes :
            ifchild.nodeType ==Node.ELEMENT_NODE :
                ifchild.tagName =="title":
                    print"Title : " , self.getText(child.firstChild)
                ifchild.tagName =="author":
                    self.handle_author(child)
                ifchild.tagName =="pubdate":
                    print"Pubdate : " , self.getText(child.firstChild)
             
    defgetText(self,node):
        ifnode.nodeType ==Node.TEXT_NODE :
            returnnode.nodeValue
        else:return ""
         
    defhandle_author(self,node):
        author= node.firstChild
        forchild in author.childNodes:
            ifchild.nodeType ==Node.ELEMENT_NODE:
                ifchild.tagName =="firstname" :
                    print"Firstname : ", self.getText(child.firstChild)
                ifchild.tagName =="lastname" :
                    print"Lastname : " , self.getText(child.firstChild)
     
     
doc =minidom.parse("book.xml")
for child in doc.childNodes :
    ifchild.nodeType ==Node.COMMENT_NODE:
        print"Conment : " , child.nodeValue
    ifchild.nodeType ==Node.ELEMENT_NODE:
        bookscanner(child)

  

输出结果:

Conment : This is a simple xml.
********************
Book id : 1001
Title : An apple
Firstname : Peter
Lastname : Zhang
Pubdate : 2012-1-12
********************
Book id : 1002
Title : Love
Firstname : Mike
Lastname : Li
Pubdate : 2012-1-10
********************
Book id : 1003
Title : Steve.Jobs
Firstname : Tom
Lastname : Wang
Pubdate : 2012-1-19
********************
Book id : 1004
Title : Harry Potter
Firstname : Peter
Lastname : Chen
Pubdate : 2012-11-11


0 0