查看文章
[原创]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′