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文件


假设有一下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 elemif __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′