• 1. tag 标签:string对象,表示数据代表的种类。
  • 2. attrib 属性:dictionary对象,表示附有的属性。
  • 3. text:string对象,表示element的内容。
  • 4. tail:string对象,表示element闭合之后的尾迹。
  • 5. 若干子元素(child elements)。
  • Python 中处理 xml 文件有三种方式:

  • xml.dom:适合用于处理 DOM API。它能够将 XML 数据在内存中解析成一个树,然后通过对树的操作来操作 XML。但是这种方式由于将 XML 数据映射到内存中的树,导致比较慢,且消耗更多内存
  • xml.sax:Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析 XML 的过程中触发一个个的事件并调用用户定义的回调函数来处理 XML 文件。
  • xml.etree.ElementTree 就像一个轻量级的 DOM,具有方便友好的 API。代码可用性好,速度快,消耗内存少。
  • 注: 因DOM需要将 XML 数据映射到内存中的树,一是比较慢,二是比较耗内存,而 SAX 流式读取 XML 文件,比较快,占用内存少,但需要用户实现回调函数(handler)
  • Python 中 ElementTree 模块

  • ElementTree 是 Python 中内置的模块
  • 通过 import xml.etree.ElementTree 导入
  • ElementTree 模块中属性方法,如下
  • tag  获取节点名称
  • attrib  属性
  • text  文本
  • tail  附加文本
  • 可以通过索引取值操作获取子节点
  • < gdppc1 > 141100 </ gdppc1 > test < neighbor1 name ="Austria" direction ="E" /> < neighbor1 name ="Switzerland" direction ="W" /> </ country1 > < country2 name ="Singapore" > < rank2 updated ="no" > 5 </ rank2 > < year2 > 2011 </ year2 > < gdppc2 > 59900 </ gdppc2 > < neighbor2 name ="Malaysia" direction ="N" /> </ country2 > </ data >
    import xml.etree.ElementTree as ET
    et = ET.parse("xmlfile")
    root = et.getroot()
    print(root.tag)     # data
    print(root[0].tag)  # country1
    print(root[1].tag)  # country2
    print(root[0].attrib)  # {'name': 'Liechtenstein'}
    print(root[0][1].text)  # 2008
    print(root[0][2].tail)  # test
    for r in root:
        print(r.tag)
    # 结果如下
    country1
    country2
  • ElementTree 模块中 ElementTree 类方法,如下
  • parse(source,parser=None)  将外部 XML 文件加载到元素树中。source 是一个文件名或文件对象。Parser 是一个可选的解析器实例。如果没有给出,则使用标准 XMLParse r解析器。返回一个 ElementTree 实例。
  • getroot()  返回此树的根元素
  • write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None, method="xml", *, short_empty_elements=True)
  • 将元素树作为 XML 写入文件。
  • file 是一个文件名,或一个为写入而打开的文件对象。
  • encoding 是输出编码(默认为 US-ASCII)。
  • xml_declaration 控制是否应该将 XML 声明添加到文件中。如果不是 US-ASCII 或 UTF-8 或 Unicode,则使用 False 表示从不,True 表示总是,None 仅表示 None(默认为 None)。
  • default_namespace 设置默认的 XML 名称空间(对于 “xmlns”)。
  • method 是 “xml”,“html” 或 “text”(默认是 “xml”)。
  • 仅限关键字的 short_empty_elements 参数控制不包含内容的元素的格式。
  • 如果为 True(默认值),则它们作为单个自闭标记发出,否则它们作为一对开始/结束标记发出。
  • clear()   重置一个元素。清除指定节点元素的所有属性
  • get(key, default=None)  获取名为 key 的元素属性。返回属性值,如果未找到该属性,则返回默认值
  • items()  以(名称、值)对序列的形式返回元素属性。属性以任意顺序返回。
  • keys()  以列表形式返回元素属性名称。名称以任意顺序返回。
  • set(key, value)  将元素上的属性 key 设置为 value。
  • et = ET.parse( " xmlfile " ) root = et.getroot() # attr = root[0].attrib # 获取到country1节点属性 # attr.clear() # 清除country1节点中的所有属性,这仅仅是在内存中删除了,xml文件中的内容没有改变 # et.write("xmlfile") # #将内存中的数据写入xml文件中,此时xml文件中的内容才发生改变 rank1 = root[0][0] print (rank1.get( " updated " )) # yes -- get取出对于属性的值 print (rank1.get( " aaa " )) # 当元素key不存在时返回None rank1.set( " name " , " Evan " ) # 给节点元素添加属性 et.write( " xmlfile " ) neighbor1 = root[0][3 ] print (neighbor1.keys()) # ['direction', 'name'] print (neighbor1.items()) # [('direction', 'E'), ('name', 'Austria')]
  • 查找元素方法
  • findall()  仅查找当前元素的直接子元素中带有指定标签的元素。
  • find()   查找当前元素带有特定标签的第一个 子级,并返回子级中的元素。
  • 可以用 Element.text 访问元素的文本内容。 Element.get 访问元素的属性
  • iter()  根据元素名进行深度优先遍历特点节点
  • <gdppc>141100</gdppc> test <neighbor direction= " E " name= " Austria " /> <neighbor direction= " W " name= " Switzerland " /> </country> <country name= " Singapore " > <rank updated= " no " >5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor direction= " N " name= " Malaysia " /> </country> </data> # find 和 findall 用法 import xml.etree.ElementTree as ET et = ET.parse( " xmlfile " ) root = et.getroot() print (root.find( " country " )) # <Element 'country' at 0x000000000120D598> print (root.findall( " country " )) # [<Element 'country' at 0x000000000120D598>, <Element 'country' at 0x00000000014CCE08>] print (root.find( " country " ).get( " name " )) # dcs print (root.find( " country " ).attrib) # {'name': 'dcs'} for node in root.iter( ' rank ' ): print ([node.tag, node.attrib, node.text]) ['rank', {'name': 'Evan', 'updated': 'yes'}, '2'] ['rank', {'updated': 'no'}, '5']
  • del  删除节点,删除当前元素索引指定的子级。
  • remove  删除节点,只能删除当前节点的子节点
  • <gdppc>141100</gdppc> test <neighbor direction= " E " name= " Austria " /> <neighbor direction= " W " name= " Switzerland " /> </country> <country name= " Singapore " > <rank updated= " no " >5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor direction= " N " name= " Malaysia " /> </country> </data> # del 和 remove 删除节点操作如下 import xml.etree.ElementTree as ET # del 删除节点 et = ET.parse("xmlfile") root = et.getroot() # print(root[0][1].tag) # year del root[0][1] # 删除第一个country节点下year节点 et.write("xmlfile") for r in root[0]: # 通过遍历root[0],拿到country下的所有节点元素对象 print(r.tag) # 再通过tag取出country下的所有节点元素对象的节点名称 # remove 删除节点 tree = ET.parse( ' xmlfile ' ) root = tree.getroot() root.remove(root.findall( " country " )) # 删除了第一个country节点 root.remove(root.findall( " country " )[1]) # 删除了第二个country节点 tree.write( " xmlfile " ) # for i in root.findall('country'): # 找到所用的country节点 # if i.find('year').text == '2008': # country节点中有year子节点,且year元素的值是‘2008’,就删除此country节点 # root.remove(i) # 当前节点是root,子节点i是拥有2008值的year节点的country节点 # tree.write('xmlfile')
  • 修改 XML 文件
  • 使用 Element.text 修改文本字段。
  • 使用 Element.set() 方法添加和修改属性。
  • 使用 Element.append() 添加新的子元素。将元素子元素添加到此元素内部子元素列表的末尾。如果 subelement 不是 Element 则引发 TypeError
  • 修改现有的节点
  • root
    = et.getroot() for node in root.iter( ' year ' ): node.text = ' 2012 ' # 将元素名位year的值修改为2012 node.set( ' Zodiac ' , ' monkey ' ) # 给year元素添加/修改属性,<year Zodiac="monkey">2012</year> et.write( ' xmlfile ' , encoding= ' UTF-8 ' ) tree = ET.parse( ' xmlfile ' ) root = tree.getroot() sub = ET.fromstring( ' <myyear/> ' ) # 准备要添加的元素名 for item in root.iter( ' country ' ): # 要加在哪个字段下,这里是将myyear加在country下面 item.append(sub) for item in root.iter( ' myyear ' ): item.text = ' 永恒,当前 ' # 给myyear元素添加元素值 item.set( ' 末日 ' , ' 到了 ' ) # 给myyear元素添加/修改属性,<year 末日="到了">2012</year> tree.write( ' xmlfile ' , encoding= ' UTF-8 ' ) root = tree.getroot() for item in root.iter( ' country ' ): # 要加在哪个字段下,这里是将myyear加在country下面 ET.SubElement(item, ' myyear ' ) # 前面是要添加在哪个字段下;后面是要添加的元素名 for item in root.iter( ' myyear ' ): item.text = ' 永恒,当前 ' # 给myyear元素添加元素值 item.set( ' 末日 ' , ' 到了 ' ) # 给myyear元素添加/修改属性,<year 末日="到了">2012</year> tree.write( ' xmlfile ' , encoding= ' UTF-8 ' )