[python] python xml ElementTree

python xml ElementTree

xml示例

<?xml version="1.0" encoding="utf-8"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
</data>

XML是中结构化数据形式,在ET中使用ElementTree代表整个XML文档,并视其为一棵树,Element代表这个文档树中的单个节点。

解析xml

从硬盘读取xml

(cElementTree为c版本的,速度快,ElementTree为python版本,速度稍慢,有c版本就用c的)

try:  
    import xml.etree.cElementTree as ET  
except ImportError:  
    import xml.etree.ElementTree as ET  
tree = ET.parse(self.tempfilename)  #打开xml文档
root = tree.getroot()               #拿到根节点

element对象属性

图片描述

  1. tag: string对象,表示数据代表的种类。
  2. attrib: dictionary对象,表示附有的属性。
  3. text: string对象,表示element的内容。
  4. tail: string对象,表示element闭合之后的尾迹。
  5. 若干子元素(child elements)。

节点操作

Element.iter(tag=None): [return list] 遍历 该Element所有后代,指定tag进行遍历寻找。
Element.findall(path):[return list]查找当前元素下tag或path能够匹配的 直系节点
Element.find(path):[return element]查找当前元素下tag或path能够匹配的 首个直系节点
Element.text: 获取当前元素的text值。
Element.get(key, default=None):获取元素指定key对应的属性值,如果没有该属性,则返回default值。

>>> for child in root:
...   print child.tag, child.attrib
...
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}

>>> for neighbor in root.iter('neighbor'):
...   print neighbor.attrib
...
{'name': 'Austria', 'direction': 'E'}
{'name': 'Switzerland', 'direction': 'W'}
{'name': 'Malaysia', 'direction': 'N'}
{'name': 'Costa Rica', 'direction': 'W'}
{'name': 'Colombia', 'direction': 'E'}

本次没有进行写操作,所以没研究,先略过。

xml编码问题

这次被python的编码坑了一次。
在网上发现了这么一段话:
python中dom和ElementTree只支持utf-8文件的解析,所以在解析之前不管用什么方法,最好确保文件是utf-8格式的,话说python的文本操作通常用utf-8都是没什么问题的,其它编码方式多多少少都有些麻烦,所以生成文件的时候尽量少用中文编码!
使用utf-8,如果涉及跨平台的时候不要带BOM,也可以采用GBK(尽量不用),但就是 不能使用utf16
然而这次要批量处理的xml居然就是utf-16的,心中一万只羊驼跑过!!!

utf-16编码直接按照上述方法Load进来,会报错:  
ParseError: encoding specified in XML declaration is incorrect: line 1, column 30

先将xml解析成utf8格式,然后替代第一行的encoding格式,然后保存一个新文件,提供后续解析。

import codecs
f = codecs.open(file_name, 'rb','utf-16')   
text = f.read().encode('utf-8')   
text = text.replace('<?xml version="1.0" encoding="utf-16"?>','<?xml version="1.0" encoding="utf-8"?>')  
f.close()  
tempfilename = file_name.split('.xml')[0]+'temp.xml'  
f = open(tempfilename, 'wb')   
f.write(text)   
f.close()

无意之间用查了一下文件的编码,发现我要处理的xml编码是用utf-8,但是头文件写的是utf-16,所以我上边就不需要codecs.open,直接用open就好了,再把头replace。

linux vim命令 :set fileencoding

Reference

http://blog.csdn.net/gingerredjade/article/details/21944675
http://www.cnblogs.com/CheeseZH/p/4026686.html
http://www.jb51.net/article/67120.htm
http://blog.csdn.net/whzhcahzxh/article/details/33735293
http://blog.csdn.net/jnbbwyth/article/details/6991425/
http://www.cnblogs.com/findumars/p/3620076.html
http://blog.csdn.net/guang11cheng/article/details/7491715

posted @ 2017-09-20 16:43  战侠歌1994  阅读(729)  评论(0编辑  收藏  举报