Chinaunix首页 | 论坛 | 博客
  • 博客访问: 245672
  • 博文数量: 68
  • 博客积分: 2802
  • 博客等级: 少校
  • 技术积分: 614
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-11 15:38
文章存档

2013年(3)

2012年(15)

2011年(21)

2010年(29)

我的朋友

分类: LINUX

2011-12-06 16:46:10

转载来源:http://blog.csdn.net/tpfly/article/details/3948029

  DOM把xml每个元素、属性、文本等信息储存在称为节点的数据类型中,xml.dom中Node(节点)是xml文档中每一个component
的父类。XML 中最常见的节点类型包括:
*元素:元素是 XML 的基本构造模块。通常,元素拥有子元素、文本节点,或两者的组合。元素节点也是能够拥有属性的唯一节点类型。
*属性:属性节点包含关于元素节点的信息,但是并不实际认为是元素的孩子,比如在下面的例子中:
*文本:文本节点就是名副其实的文本。它可以由更多信息组成,也可以只包含空白。
*文档:文档节点是文档中其他所有节点的父亲。
其他节点类型不太常用,但是在某些场合下仍然是必需的。它们包括:
*CDATA: 字符数据(Character Data)的缩写,这是一个特殊的节点,它包含不应该被解析器分析的信息。相反,它包含的信息应该以纯文本传递。例如,可能会为了特殊目的而存储 HTML 标签。在通常情形下,处理器可能尝试为所存储的每个标签创建元素,而这样可能导致文档不是格式良好
的。这些问题可用通过使用 CDATA 节(section)来避免。这些节使用特殊的符号来编写:
<[CDATA[
      Important:  Please keep head and hands inside ride at all
times
.
     
]]>
*注释:注释包括关于数据的信息,通常被应用程序忽略。它们写为如下形式:

*处理指令:处理指令是专门针对应用程序的信息。其中一些例子包括要执行的代码或者关于从何处寻找样式表的信息。例如:

python xml.dom中节点类型由节点中nodeType属性得到,该属性取如下值:ELEMENT_NODE,
ATTRIBUTE_NODE, TEXT_NODE, CDATA_SECTION_NODE, ENTITY_NODE,
PROCESSING_INSTRUCTION_NODE, COMMENT_NODE, DOCUMENT_NODE,
DOCUMENT_TYPE_NODE, NOTATION_NODE

示例:把上面的xml例子保存为test-utf8.xml,一定用utf8的编码保存。然后在python提示符下输入:
>>> from xml.dom import minidom
>>> xmldoc=minidom.parse('test-utf8.xml')

得到一个Document类型变量xmldoc, 它是一个保存文档所有信息的树结构。用Node的toxml()函数可以得到节点中保存的xml字符串。因为Document是Node的子类,所以可以应用toxml函数:
>>> print xmldoc.toxml()


       
                pilgrim
                http://blog.xxx.com
                博客描述
                Terac Miracle 3.8
               
                        文章标题
                        http://blog.xxx.com/e_42678.html
                        文章内容
                        Sun, 23 Sep 2007 23:32:00 +0800
               

               
                        文章标题
                        http://blog.xxx.com/e_39749.html
                        文章内容
                        Mon, 27 Aug 2007 23:58:00 +0800
               

       


要得到文档的根节点,用Document的documentElement属性:
>>> root=xmldoc.documentElement
>>> root


>>> print root.toxml()


       
                pilgrim
                http://blog.xxx.com
                博客描述
                Terac Miracle 3.8
               
                        文章标题
                        http://blog.xxx.com/e_42678.html
                        文章内容
                        Sun, 23 Sep 2007 23:32:00 +0800
               

               
                        文章标题
                        http://blog.xxx.com/e_39749.html
                        文章内容
                        Mon, 27 Aug 2007 23:58:00 +0800
               

       


root有一个子元素channel,这些子元素由root的childNodes保存,其中第一个子节点由root.firstChild引用,最后一个子节点由root.lastChild引用:

>>> print root.firstChild.toxml()
>>> print root.lastChild.toxml()
>>> print root.childNodes[1].toxml()


                pilgrim
                http://blog.xxx.com
                博客描述
                Terac Miracle 3.8
               
                        文章标题
                        http://blog.xxx.com/e_42678.html
                        文章内容
                        Sun, 23 Sep 2007 23:32:00 +0800
               

               
                        文章标题
                        http://blog.xxx.com/e_39749.html
                        文章内容
                        Mon, 27 Aug 2007 23:58:00 +0800
               

       

因为firstChild和lastChild是由channel前后的空白和换行形成的文本型节点,所以会打印出空行。
访问xmldoc:
xml各部分与minidom关系对应:
attributes可以像dict一样使用,用keys()得到属性列表,用Node.attributes['key'].value得到属性值

        Node.childNodes保存个子节点,第一个节点Node.firstChild,最后一个Node.lastChild,可以像list一样使用。
        TextNode.data

修改xmldoc:
添加节点:首先创建节点:Document.createElement(tagName)
Document.createTextNode(data)再把节点添加到Node下面:Node.appendChild()
node.insertBefore(new,ref)
删除节点Node.removeChild()
替换节点 Node.replaceChild(new,old)
添加删除属性 更改属性
Element.setAttribute(name,value) Element.removeAttribute(name) 也可以用
Element.attributes['key']=value来直接指定,value是unicode字符串。

4 例子
dir2xml.py是由目录结构生成xml文件的例子,xml2dir.py是根据生成的xml文件内容重建目录,当然建立出的文件都是没有内容的空文件。
文件dir2xml.py:

#!/usr/bin/env python
#-*-   coding:   gbk   -*-
"""遍历目录,根据目录结构生成xml文件。
dir2xml dirname xmlfilename
"""
import os
from xml.dom import minidom as pydom
import sys
def usage():
    print "usage:",sys.argv[0],"dirname xmlfilename"

def dir2xml(dirname):
    """遍历目录,根据目录内容生成xml Document对象
    dirname是路径名,必须是标准的路径名,前后没有空格,后面不带/或//。
"""
    impl=pydom.getDOMImplementation()
    newdoc=impl.createDocument(None,"dir",None)
    rootdir=newdoc.documentElement
    rootdir.attributes['name']=os.path.basename(dirname)

    def walkdir(dirname,node,document):   #对目录递归遍历,这里用os.path.walk更简单
        for file in os.listdir(dirname):
            if os.path.isfile(os.path.join(dirname,file)):
                newFileEl=document.createElement('file')
                newFileEl.attributes['name']=file.encode('utf8')
                node.appendChild(newFileEl)
            elif os.path.isdir(os.path.join(dirname,file)):
                newFileEl=document.createElement('dir')
                newFileEl.attributes['name']=file.encode('utf8')
                node.appendChild(newFileEl)
                walkdir(os.path.join(dirname,file),newFileEl,document)
    walkdir(dirname,rootdir,newdoc)
    return newdoc

if __name__ == '__main__':
    if len(sys.argv)<3:
        usage()
        sys.exit()
    if not os.path.isdir(sys.argv[1]):
        print 'Error:',sys.argv[1],'is not a directory.'
        sys.exit()
    xmlfile=file(sys.argv[2],'w')

newdoc=dir2xml(unicode(os.path.normpath(sys.argv[1].strip()),'gb2312'))
    newdoc.writexml(xmlfile,'/n','  ')
    xmlfile.close()

文件xml2dir.py:

#!/usr/bin/env python
# -*- coding: cp936 -*-
"""由xml文档生成目录
xml2dir xmlfilename dirname
"""
import os
from xml.dom import minidom as pydom
import sys

def usage():
    print "usage:",sys.argv[0],"dirname xmlfilename"

def xml2dir(xmlElement,dirname):
    """由xml文档生成目录
    xml2dir(xmlElement,dirname)
    xmlElement是xml文档元素,标签名file表示文件,dir表示目录。属性name表示文件或目录名
    dirname是保存xmlElement整个节点的目录名,将在dirname目录中开始建立xmlElement目录树。"""
    if not os.path.exists(dirname):
        os.mkdir(dirname)
    cwd=os.getcwd()
    os.chdir(dirname)
    for childNode in xmlElement.childNodes:
        if childNode.nodeType not in
(childNode.ELEMENT_NODE,childNode.DOCUMENT_NODE):
            continue
        if childNode.tagName == u'file':
            file(childNode.attributes['name'].value,'w').close()
        elif childNode.tagName == u'dir':
            if not os.path.exists(childNode.attributes['name'].value):
                os.mkdir(childNode.getAttribute('name'))
            xml2dir(childNode,childNode.getAttribute('name'))
    os.chdir(cwd)

if __name__ == '__main__':
    if len(sys.argv)<3:
        usage()
        sys.exit()
    try:
        xmlfile=file(sys.argv[1],'r')
    except:
        sys.stderr.write("XML file not found or cannot access.")
        sys.exit()
    xmldoc=pydom.parse(xmlfile)
    xml2dir(xmldoc,os.path.normpath(sys.argv[2].strip()))
    xmlfile.close()
阅读(7056) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~