://blog.csdn.net/zhangj1012003_2007/archive/2010/04/23/5514807.aspx://blog.csdn.net/zhangj1012003_2007/archive/2010/04/22/5514935.aspx一.XML的读取.在NewEdit中有代码片段的功能,代码片段分为片段的分类和片段的内容。在缺省情况下都是用XML格式保存的。下面我讲述一下,如何使用minidom来读取和保存XML文件。下面是片段分类的一个示例文件--catalog.xml?xmlversion=1.0encoding=utf-8?catalogmaxid4/maxiditemid=1captionPython/captionitemid=4caption测试/caption/item/itemitemid=2captionZope/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信息体。头信息如:?xmlversion=1.0encoding=utf-8?它表明了此XML文档所用的版本,编码方式。有些复杂的还有一些文档类型的定义(DOCTYPE),用于定义此XML文档所用的DTD或Schema和一些实体的定义。这里并没有用到,而且我也不是专家,就不再细说了。XML信息体是由树状元素组成。每个XML文档都有一个文档元素,也就是树的根元素,所有其它的元素和内容都包含在根元素中。3.DOMDOM是DocumentObjectModel的简称,它是以对象树来表示一个XML文档的方法,使用它的好处就是你可以非常灵活的在对象中进行遍历。4.元素和结点元素就是标记,它是成对出现的。XML文档就是由元素组成的,但元素与元素之间可以有文本,元素的内容也是文本。在minidom中有许多的结点,元素也属于结点的一种,它不是叶子结点,即它存在子结点;还存在一些叶子结点,如文本结点,它下面不再有子结点。象catalog.xml中,文档元素是catalog,它下面有两种元素:maxid和item。maxid用来表示当前最大的item的id值。每一个item都有一个id属性,id属性是唯一的,在NewEdit中用来生成每个分类所对应的代码片段的XML文档名,因此不能重复,而且它是一个递增的值。item元素有一个caption子元素,用来表示此分类项的名称,它还可以包含item元素。这样,就定义了一个树状XML结构,下面让我们看一看如果把它们读出来。一、得到dom对象importxml.dom.minidomdom=xml.dom.minidom.parse('d:/catalog.xml')这样我们得到了一个dom对象,它的第一个元素应该是catalog。二、得到文档元素对象root=dom.documentElement这样我们得到了根元素(catalog)。三、结点属性每一个结点都有它的nodeName,nodeValue,nodeType属性。nodeName为结点名字。root.nodeNameu'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.nodeType1root.ELEMENT_NODE1四、子元素、子结点的访问访问子元素、子结点的方法很多,对于知道元素名字的子元素,可以使用getElementsByTagName方法,如读取maxid子元素:root.getElementsByTagName('maxid')[DOMElement:maxidat0xb6d0a8]这样返回一个列表,由于我们的例子中maxid只有一项,因此列表也只有一项。如果想得到某个元素下的所有子结点(包括元素),可以使用childNodes属性:root.childNodes[DOMTextnode\n,DOMElement:maxidat0xb6d0a8,DOMTextnode\n,DOMElement:itemat0xb6d918,DOMTextnode\n,DOMElement:itemat0xb6de40,DOMTextnode\n,DOMElement:itemat0xb6dfa8,DOMTextnode\n]可以看出所有两个标记间的内容都被视为文本结点。象每行后面的回车,都被看到文本结点。从上面的结果我们可以看出每个结点的类型,本例中有文本结点和元素结点;结点的名字(元素结点);结点的值(文本结点)。每个结点都是一个对象,不同的结点对象有不同的属性和方法,更详细的要参见文档。由于本例比较简单,只涉及文本结点和元素结点。getElementsByTagName可以搜索当前元素的所有子元素,包括所有层次的子元素。childNodes只保存了当前元素的第一层子结点。这样我们可以遍历childNodes来访问每一个结点,判断它的nodeType来得到不同的内容。如,打印出所有元素的名字:fornodeinroot.childNodes:ifnode.nodeType==node.ELEMENT_NODE:printnode.nodeNamemaxiditemitem对于文本结点,想得到它的文本内容可以使用:.data属性。对于简单的元素,如:captionPython/caption,我们可以编写这样一个函数来得到它的内容(这里为Python)。defgetTagText(root,tag):node=root.getElementsByTagName(tag)[0]rc=fornodeinnode.childNodes:ifnode.nodeTypein(node.TEXT_NODE,node.CDATA_SECTION_NODE):rc=rc+node.datareturnrc这个函数只处理找到的第一个符合的子元素。它会将符合的第一个子元素中的所有文本结点拼在一起。当nodeType为文本类结点时,node.data为文本的内容。如果我们考查一下元素caption,我们可能看到:[DOMTextnodePython]说明caption元素只有一个文本结点。如果一个元素有属性,那么可以使用getAttribute方法,如:itemlist=root.getElementsByTagName('item')item=itemlist[0]item.getAttribute('id')u'1'这样就得到了第一个item元素的属性值。下面让我们简单地小结一下如何使用minidom来读取XML中的信息1.导入xml.dom.minidom模块,生成dom对象2.得到文档对象(根对象)3.通过getElementsByTagName()方法和childNodes属性(还有其它一些方法和属性)找到要处理的元素4.取得元素下文本结点的内容二.写入.下面我来演示一下如何从无到有生成象catalog.xml一样的XML文件。一、生成dom对象importxml.dom.minidomimpl=xml.dom.minidom.getDOMImplementation()dom=impl.createDocument(None,'catalog',None)这样就生成了一个空的dom对象。其中catalog为文档元素名,即根元素名。二、显示生成的XML内容每一个dom结点对象(包括dom对象本身)都有输出XML内容的方法,如:toxml(),toprettyxml()toxml()输出紧凑格式的XML文本,如:catalogitemtest/itemitemtest/item/catalogtoprettyxml()输出美化后的XML文本,如:catalogitemtest/itemitemtest/item/catalog可以看出,它是将每个结点后面都加入了回车符,并且自动处理缩近。但对于每一个元素,如果元素只有文本内容,则我希望元素的tag与文本是在一起的,如:itemtest/item而不想是分开的格式,但minidom本身是不支持这样的处理。关于如何实现形如:catalogitemtest/itemitemtest/item/catalog这样的XML格式,后面我们再说。三、生成各种结点对象dom对象拥有各种生成结点的方法,下面列出文本结点,CDATA结点和元素结点的生成过程。1.文本结点的生成text=dom.createTextNode('test')test要注意的是,在生成结点时,minidom并不对文本字符进行检查,象文本中如果出现了'','&'之类的字符,应该转换为相应的实体符号'<','&'才可以,这里没有做这个处理。2.CDATA结点的生成data=dom.createCDATASection('aaaaaa\nbbbbbb')data.toxml()'![CDATA[aaaaaa\nbbbbbb]]'CDATA是用于包括大块文本,同时可以不用转换'','&'字符的标记,它是用![CDATA[文本]]来包括的。但文本中不可以有]]这样的串存在。生成结点时minidom不作这些检查,只有当你输出时才有可能发现有错。3.元素结点的生成item=dom.createElement('caption')item.toxml()'caption/'对于象元素这样的结点,生成的元素结点其实是一个空元素,即不包含任何文本,如果要包含文本或其它的元素,我们需要使用appendChild()或insertBefore()之类的方法将子结点加就到元素结点中。如将上面生成的text结点加入到caption元素结点中:item.appendChild(text)DOMTextnodetestitem.toxml()'captiontest/caption'使用元素对象的setAttribute()方法可以向元素中加入属性,如:item.setAttribute('id','idvalue')item.toxml()'capti