整理网上python解析xml文件相关资料汇总

  查看文章  

[原创]python--------xml 读写 修改 删除
2011-11-25 13:37
python本身的模块用的不是很顺手,所以就顺手封装了个类,这下顺手了,我顺手不代表其他人用的顺手,因为不是教程贴,所以有时间在解释下这个程序

#!/usr/bin/python

# coding=gbk

'''

Created on 2011-11-22

 

@author: Sruing

'''

 

import xml.etree.ElementTree as etree

import os

 

#全局变量用于返回找到的节点

resultOfChild = ''

resultOfParents = ''

#---------------------------------------------------------------------------------------------

class handleXML():

    #初始化类

    def __init__(self,fileName):

        #读入的文件名

        self.fileName = fileName

        #判断XML是否存在

        #存在

        if os.path.isfile(self.fileName) == True:

            #解析XML文件 

            self.tree = etree.parse(self.fileName)

        #不存在

        else:

            #文件不存在创建新文件

            print "The file doesn't exist! please input a tagname for root.\n"

            self.rootTagName = raw_input("Your root here:\n")

            self.creatRootTag(self.rootTagName)

            print "The file have been successfully created!"

            #解析创建的文件

            self.tree = etree.parse(self.fileName)

        #获取XML树的root

        self.root = self.tree.getroot()

        #用于删除节点是标记子节点

        self.exits = False

        #

        return

#----------------------------------------------------------------------------------------------- 

    #文件不存在在类初始化中调用此方法,创建根节点

    def creatRootTag(self,rootTagName):

        #新建文件内容

        self.fileContent = "<" + rootTagName + ">" + "</" + rootTagName + ">"

        xmlFile = file(self.fileName,'w')

        xmlFile.write(self.fileContent)

        xmlFile.close()

        return

#--------------------------------------------------------------------------------------------------

    #寻找指定的节点

    def findTag(self,tag,initRoot = ""):

        global resultOfChild

        #默认参数为空为从根节点查找

        if initRoot is "":initRoot = self.root

        #递归退出条件

        if resultOfChild is '':

            #查找当前节点下的子节点

            for self.children in initRoot.getchildren():

                if self.children.tag == tag:

                    resultOfChild = self.children

                    break

                else:

                    self.findTag(tag,self.children)

        #返回找到的节点

        return resultOfChild

#--------------------------------------------------------------------------------------------------

    #寻找指定节点的父节点

    def findFatherTag(self,tag,initRoot = ""):

        global resultOfParents

        #默认参数为空为从根节点查找

        if initRoot is "":initRoot = self.root

        #递归退出条件

        if resultOfParents is '':

            #查找当前节点下的子节点

            for self.children in initRoot.getchildren():

                if self.children.tag == tag:

                    resultOfParents = initRoot

                    break

                else:

                    self.findFatherTag(tag,self.children)

        #返回找到的节点的父节点

        return resultOfParents

#--------------------------------------------------------------------------------------------------

    #创建根节点的直接子节点

    def creatDirectSubTag(self,subTag):

        self.subTag = subTag

        etree.SubElement(self.root,self.subTag)

        self.tree.write(self.fileName)

        return

#--------------------------------------------------------------------------------------------------      

    #创建根节点的非直接子节点

    def creatIndirectSubTag(self,fatherTag,SonTag):

        #self.fatherTag = self.tree.findall(fatherTag)

        self.fatherTag = self.findTag(fatherTag)

        #print type(self.findTag(fatherTag))

        self.SonTag = SonTag

        #etree.SubElement(self.fatherTag[0], self.SonTag)

        etree.SubElement(self.fatherTag, self.SonTag)

        self.tree.write(self.fileName)

        return

#---------------------------------------------------------------------------------------------------   

    #添加节点属性

    def addNodeAttribute(self,tag,attribute,value):

        self.tag = self.findTag(tag)

        #print type(self.tag)

        self.attribute = attribute

        self.value = value

        self.tag.set(self.attribute,self.value)

        self.tree.write(self.fileName)

        return

#----------------------------------------------------------------------------------------------------  

    #添加节点文本

    def addNodeText(self,tag,text):

        self.tag = self.findTag(tag)

        #print type(self.tag)

        self.text = text

        self.tag.text = self.text

        self.tree.write(self.fileName)

        return

#------------------------------------------------------------------------------------------------------

    #删除节点

    def delNode(self,tag):

        self.fatherTag = self.findFatherTag(tag)

        #print self.fatherTag

        self.sonTag = self.findTag(tag)

        #print self.sonTag

        self.fatherTag.remove(self.sonTag)

        self.tree.write(self.fileName)

        return

#-------------------------------------------------------------------------------------------------------
 

 

 

请问用python怎么修改xml的节点值?

如:<string>win xp</string>怎么把win xp修改为xin 7.
最佳答案

from xml.etree import ElementTree
filePath = 'd:\\aaa.xml'
xmldoc = ElementTree.parse(filePath)
node = xmldoc.find('./string')
node.text = "win 7"

追问
我这样写之后,为什么我的xml里的值没有变化?
回答
他是改变不了原xml里的值的,需要你写到一个新的xml文件里
xmldoc.write(path)
 

 

 

 

python之操作xml文件
 
小鱼儿 发表于 2007-10-18 14:29:00
 


假设有一下xml文件:
Sample.xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<policy-list>
<policy id="123456">
<group>1</group>
</policy>
</policy-list>
</configuration>

from elementtree.ElementTree as ET
如果你使用的是python2.5的话:
import xml.etree.ElementTree as ET

tree = ET.parse("path/to/Sample.xml")
doc = tree.getroot()         #获得根

元素的标签名字 : print doc.tag  #@result: configuration
Element text: print doc.text  #@result: "\n"  如果所有元素是一行的话,结果为空

子元素

迭代子元素: for child in doc
for child in doc:
    print child.tag        #@result: policy-list 自由policy-list一个子元素
获得第1、2个子元素: doc[0:2]
获得节点的子元素:elem.getchildren() 返回这个节点的子元素(list)
获得名为policy-list的元素: doc.find('policy-list')
这里需要注意,由于doc是root的元素,这里不能用doc.find("policy"),来找到policy这个节点,尽管代码不会报错,但是获得是"NoneType" object,如果你调用这个对象的方法,便会报错,比如 policy = doc.find("policy")   policy.find("group"),第一句不会报错,但是第二句就会报错,因为policy是一个NoneType object
append(), remove(), insert()方法
g2 = ET.Element("group")
g2.text = "3"
p2 = ET.Element("policy")
p2.set("id","122334")
p2.append(g2)  #policy下面增加一个group节点
policylist = doc.find("policy-list")
policylist.append(p2) #policy-list下面增加一个policy节点
tree.write("path/to/Sample.xml") #写入文件

insert(index,elem) #在制定的index插入一个元素

del elem[n] #删除第n个节点
elem.remove(elem2) #从节点elem中删除elem2子节点

getiterator(tag) 返回一个列表,或者另外一个迭代对象
节点的属性操作

获得节点的属性key列表: policy.keys()#@result: ["id"]
获得节点的属性数组: policy.items()   #@result: ["id","123456"]
测试节点是否包含某个属性(NAME):
if policy.get('NAME') is not None, or
if 'NAME' in book.attrib
获得属性 id的值:
policy.attrib.get('id'), or
policy.get('id')
给属性赋值: policy.set('Name', 'httppolicy')
保存修改后的文件 tree.write("path/to/Sample.xml")
另外几种保存方法,上面这种保存的文件是ascii格式的,如果要保存为utf-8的,可以用这种方式,
f = open("path/to/Sample.xml","w")
tree.write(f,"utf-8")
创建节点
elem.makeelement(tag,attr_dict)
example: feed = root.makeelement('feed',{'version':'0.22'})

ET.Element(tag,attr_dict,**extra)
policy = ET.Element("policy",{"id":"12121"})

ET.SubElement(parent,tag,attr_dict,**extra)
group = ET.SubElement(policy,"group")

 
 

 

 

from xml.etree.ElementTree import ElementTree
from xml.etree.ElementTree import Element
from xml.etree.ElementTree import SubElement
from xml.etree.ElementTree import dump
from xml.etree.ElementTree import Comment
from xml.etree.ElementTree import tostring

'''
<?xml version="1.0"?>
<PurchaseOrder>
  <account refnum="2390094"/>
  <item sku="33-993933" qty="4">
    <name>Potato Smasher</name>
    <description>Smash Potatoes like never before.</description>
  </item>
</PurchaseOrder>
'''

## Writing the content to xml document
book = ElementTree()

purchaseorder = Element('PurchaseOrder')
book._setroot(purchaseorder)

SubElement(purchaseorder,  'account', {'refnum' : "2390094"})

item = Element("item", {'sku' : '33-993933', 'qty' : '4'})
purchaseorder.append(item)
print item.items()       # [('sku', '33-993933'), ('qty', '4')]
print item.attrib        # {'sku': '33-993933', 'qty': '4'}
print item.get('sku')    # 33-993933
SubElement(item, 'name').text = "Potato Smasher"
SubElement(item, 'description').text = "Smash Potatoes like never before."

#book.write('book.xml',"utf-8")

#print tostring(purchaseorder)

#import sys
#book.write(sys.stdout)

#dump(book)

## Displaying the content of the xml document
print purchaseorder.find('account')
print purchaseorder.find('account').get('refnum')
print purchaseorder.findall('account')[0].get('refnum')

print purchaseorder.find('item/name')
print purchaseorder.find('item/name').text

## How to use ElementTree([element,] [file])
## 1. From standard XML element, it becomes root element
print ElementTree(item).getroot().find('name').text
## 2. From XML file
print ElementTree(file='book.xml').getroot().find('item/description').text


## Create an iterator
for element in purchaseorder.getiterator():
    print element.tag


## Get pretty look
def indent(elem, level=0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        for e in elem:
            indent(e, level+1)
        if not e.tail or not e.tail.strip():
            e.tail = i
    if level and (not elem.tail or not elem.tail.strip()):
        elem.tail = i
    return elem

if __name__=="__main__":
    dump(indent(purchaseorder))
    book.write('book.xml',"utf-8")

 

一、基本知识
1、插入节点
Element.insert(index, element) 、ET.SubElement(parent, tag[, attrib[, **extra]]) 、Element.append(subelement)
2、删除节点
Element.remove(subelement) 删除一个节点、Element.clear()删除该节点下所有子节点
3、在节点中插入属性
Element.set(key, value)

二、示例

Java代码 
# -*- coding:UTF-8 -*-  
 
import xml.etree.ElementTree as ET  
import xml.dom.minidom as minidom  
 
#获取根节点  
def getRoot(xmlpath):  
    '''  
    xmlpath:xml文件的路径  
    '''  
    root = ET.parse(xmlpath).getroot()  
    return root  
 
#格式化输出xml文件  
def display(root):  
      
    rough_string = ET.tostring(root, 'utf-8')  
    reparsed = minidom.parseString(rough_string)  
    print reparsed.toprettyxml(indent="  " , encoding="utf-8");  
 
 
if __name__ == '__main__':  
      
    root = ET.Element('bookList')  
      
    #==============添加节点========================  
    #向root节点下插入节点<book id='ISO001'>  
    bookE = ET.SubElement(root,'book')#方式一  
    bookE.set('id', 'ISO001')#为节点添加属性  
    #向<book>节点下插入<author>Gaosilin</version>节点  
    authorE = ET.Element('author')  
    authorE.text = 'Gaosilin'#为节点赋值  
    bookE.append(authorE)#方式二  
    ##向<book>节点下插入<name>Java</name>节点  
    nameE = ET.Element('name')  
    nameE.text = 'java' 
    bookE.insert(1,nameE)#方式三  
    #修改  
    nameE.text = '修改后的C' 
    display(root)  
    #==============删除节点========================  
    bookE.remove(nameE)#注意需删除的节点一定要是该父节点的下一级节点  
    bookE.remove(authorE)  
    bookE.clear()#删除该节点下的所有子节点,等价于上两句  
    root.remove(bookE)  
#    root.remove(nameE)#出错:因为nameE的上一级节点是bookE而不是root  
    display(root)
 

 

[Python学习]使用minidom来处理XML的示例(一)–XML的读取
 

在 NewEdit 中有代码片段的功能,代码片段分为片段的分类和片段的内容。在缺省情况下都是用XML格式保存的。下面我讲述一下,如何使用minidom来读取和保存XML文件。

下面是片段分类的一个示例文件–catalog.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<catalog>
    <maxid>4</maxid>
    <item id=”1″>
        <caption>Python</caption>
        <item id=”4″>
            <caption>测试</caption>
        </item>
    </item>
    <item id=”2″>
        <caption>Zope</caption>
    </item>
</catalog>

分类是树状结构,显示出来可能为:

Python
    测试
Zope

先简单介绍一下XML的知识,如果你已经知道了可以跳过去。

1. XML文档的编码

此XML文档的编码为utf-8,因此你看到的“测试”其实是UTF-8编码。在XML文档的处理中都是使用UTF-8编码进行的,因此,如果你不写明encoding的话,都是认为文件是UTF-8编码的。在Python中,好象只支持几种编码,象我们常用的GB2312码就不支持,因此建议大家在处理XML时使用UTF-8编码。

2. XML文档的结构

XML文档有XML头信息和XML信息体。头信息如:

<?xml version=”1.0″ encoding=”utf-8″?>

它表明了此XML文档所用的版本,编码方式。有些复杂的还有一些文档类型的定义(DOCTYPE),用于定义此XML文档所用的DTD或Schema和一些实体的定义。这里并没有用到,而且我也不是专家,就不再细说了。

XML信息体是由树状元素组成。每个XML文档都有一个文档元素,也就是树的根元素,所有其它的元素和内容都包含在根元素中。

3. DOM

DOM是Document Object Model的简称,它是以对象树来表示一个XML文档的方法,使用它的好处就是你可以非常灵活的在对象中进行遍历。

4. 元素和结点

元素就是标记,它是成对出现的。XML文档就是由元素组成的,但元素与元素之间可以有文本,元素的内容也是文本。在minidom中有许多的结点,元素也属于结点的一种,它不是叶子结点,即它存在子结点;还存在一些叶子结点,如文本结点,它下面不再有子结点。

象catalog.xml中,文档元素是catalog,它下面有两种元素:maxid和item。maxid用来表示当前最大的item的id值。每一个item都有一个id属性,id属性是唯一的,在 NewEdit 中用来生成每个分类所对应的代码片段的XML文档名,因此不能重复,而且它是一个递增的值。item元素有一个caption子元素,用来表示此分类项的名称,它还可以包含item元素。这样,就定义了一个树状XML结构,下面让我们看一看如果把它们读出来。

一、得到dom对象

>>> import xml.dom.minidom
>>> dom = xml.dom.minidom.parse(‘d:/catalog.xml’)

这样我们得到了一个dom对象,它的第一个元素应该是catalog。

二、得到文档元素对象

>>> root = dom.documentElement

这样我们得到了根元素(catalog)。

三、结点属性

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

>>> root.nodeName
u’catalog’

nodeValue是结点的值,只对文本结点有效。nodeType是结点的类型,现在有以下几种:

‘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是ELEMENT_NODE类型。

>>> root.nodeType
1
>>> root.ELEMENT_NODE
1

四、子元素、子结点的访问

访问子元素、子结点的方法很多,对于知道元素名字的子元素,可以使用getElementsByTagName方法,如读取maxid子元素:

>>> root.getElementsByTagName(‘maxid’)
[<DOM Element: maxid at 0xb6d0a8>]

这样返回一个列表,由于我们的例子中maxid只有一项,因此列表也只有一项。

如果想得到某个元素下的所有子结点(包括元素),可以使用childNodes属性:

>>> root.childNodes
[<DOM Text node "\n    ">, <DOM Element: maxid at 0xb6d0a8>, <DOM Text node "\n    ">, <DOM Element: item at 0xb6d918>, <DOM Text node "\n    ">, <DOM Element: item at 0xb6de40>, <DOM Text node "\n    ">, <DOM Element: item at 0xb6dfa8>, <DOM Text node "\n">]

可以看出所有两个标记间的内容都被视为文本结点。象每行后面的回车,都被看到文本结点。从上面的结果我们可以看出每个结点的类型,本例中有文本结点和元素结点;结点的名字(元素结点);结点的值(文本结点)。每个结点都是一个对象,不同的结点对象有不同的属性和方法,更详细的要参见文档。由于本例比较简单,只涉及文本结点和元素结点。

getElementsByTagName可以搜索当前元素的所有子元素,包括所有层次的子元素。childNodes只保存了当前元素的第一层子结点。

这样我们可以遍历childNodes来访问每一个结点,判断它的nodeType来得到不同的内容。如,打印出所有元素的名字:

>>> for node in root.childNodes:
    if node.nodeType == node.ELEMENT_NODE:
        print node.nodeName
       
maxid
item
item

对于文本结点,想得到它的文本内容可以使用: .data属性。

对于简单的元素,如:<caption>Python</caption>,我们可以编写这样一个函数来得到它的内容(这里为Python)。

def getTagText(root, tag):
    node = root.getElementsByTagName(tag)[0]
    rc = “”
    for node in node.childNodes:
        if node.nodeType in ( node.TEXT_NODE, node.CDATA_SECTION_NODE):
            rc = rc + node.data
    return rc

这个函数只处理找到的第一个符合的子元素。它会将符合的第一个子元素中的所有文本结点拼在一起。当nodeType为文本类结点时,node.data为文本的内容。如果我们考查一下元素caption,我们可能看到:

[<DOM Text node "Python">]

说明caption元素只有一个文本结点。

如果一个元素有属性,那么可以使用getAttribute方法,如:

>>> itemlist = root.getElementsByTagName(‘item’)
>>> item = itemlist[0]
>>> item.getAttribute(‘id’)
u’1′

 

 

你可能感兴趣的:(xml,python,File,文档,import,encoding)