天天看点

个人学习笔记:Python处理xml文件

1.1、什么是xml?

xml指的是可扩展标记语言(EXtensible Markup Language),其与HTML很像但设计用途不同:

(1)XML被设计用来传输和存储数据,其焦点是数据的内容;

(2)HTML被设计用来显示数据,其焦点是数据的外观;

(3)XML只提供一种数据存储和传输的的框架格式,并未预先定义相关标签,需要自行定义标签和文档结构;

(4)XML是独立于软件和硬件的信息传输工具;

1.2、xml文档的构成要素

1.2.1、xml元素

xml元素是指从开始标签到结束标签,且包含开始与结束部分的一个文档块。

(1)所谓标签,xml中的标签都是以标签对构成的,一对标签分别表示了元素的开始和结束,即----,其中一个标签对中的string相同;

(2)一个元素可以包含——其他元素,文本、属性以及这三种的混合;

1.2.2、xml属性

xml属性是对元素的额外信息说明,其依赖于元素存在,提供关于元素的额外信息;

如下:

<file type="gif">computer.gif</file>
           

type即元素的属性。

另外,属性需要遵循如下原则:

(1)属性值必须被引号包围,不过单引号和双引号均可使用;

(2)如果属性值本身包含双引号,则可以使用单引号避免歧义;

(3)尽力避免使用属性而多使用元素——

属性不能包含多值,但元素可以;

属性不能包含树结构,但元素可以;

属性不容易扩展;

1.2.3、xml的语法规则

xml文档必须遵循如下规则:

(1)所有的元素都必须有开始标签和结束标签,不可以省略标签;

(2)xml对大小写敏感,会对其分别作为两个标签处理;

(3)xml文档必须包含根元素,其是文档中其他所有元素的父元素;

(4)xml必须正确嵌套,父元素要完全包住子元素;

(5)xml的声明文件为文档可选部分,如果存在则需要放置文档第一行,说明xml版本和编码形式等信息,如下所示:

<?xml version="1.0" encoding="utf-8"?>

(6)XML 属性值必须加引号,且特定的属性名称在同一个元素标记中只能出现一次;

(7)对于xml文字中的一些特殊含义的字符,如"<",将其放在xml元素中会发生错误,需要进行实体引用进行替代,如:

“<”>"<";

“>”>">";

“&”>"&";

“apos;”>" '";

“quot;”==>" " ";

(8)xml文档中的注释语法如下:

<!-- This is a comment -->

2、Python操作示例

<?xml version="1.0" encoding="utf-8"?>
<bookstore>
    <book category="CHILDREN">
        <title>Harry Potter</title>
        <author>J K. Rowling</author>
        <year>2005</year>
        <price>29.99</price>
    </book>
    <book category="WEB">
        <title>Learning XML</title>
        <author>Erik T. Ray</author>
        <year>2003</year>
        <price>39.95</price>
    </book>
</bookstore>
           

上述示例中:

第一行为XML声明;

根元素为;

为嵌套的元素,category为该元素的属性;

import xml.etree.ElementTree as ET
tree = ET.parse("./test.xml")
#获取根节点
root = tree.getroot()
           
##元素的属性及方法
#help(root)
###数据描述属性:
print("以字典形式显示元素(节点)的属性及属性值:",root.attrib)
print("元素标签名称(根节点名):",root.tag)
print("直接跟在开始标签之后的文本内容:",root.text)
print("直接跟在结束标签之后的文本内容:",root.tail)

###元素方法:
#find()方法:按照子节点名称对本层节点下的下一层节点进行查找获取一个查找对象
mo = root.find("movie")
print(f"子节点名称为{mo.tag};属性值为{mo.attrib};")

#findall()方法:是获取所有该名称的子节点,结果存为一个列表;
root.findall("movie")

#以取值元组对的形式访问属性及属性值:
##key()方法、get()方法、items()方法都是对标属性键值对的字典方法
for att,val in root.items():
    print("属性为:",att)
    print("属性值:",val)

#对于根节点下所有节点的遍历访问
## 使用list(element)的方法访问下一层所有的子节点
for chd in list(root):
     print(f"{root.tag}的叶子节点:名称为{chd.tag},属性{chd.attrib};")
## 访问所有的结点
for node in root.iter():
    print(f"结点名:{node.tag},属性字典:{node.attrib};")

## 存在一个方法iterfind()其是find()的方法的内置,即find()方法根本上是对iterfind()的调用
###iterfind()返回的是一个生产器,是当前结点下的子结点而非所有结点;
###find(elem)本质上即等价于list(iterfind(elem));
           
以字典形式显示元素(节点)的属性及属性值: {'shelf': 'New Arrivals'}
元素标签名称(根节点名): collection
直接跟在开始标签之后的文本内容: 

直接跟在结束标签之后的文本内容: None
子节点名称为movie;属性值为{'title': 'Enemy Behind'};
属性为: shelf
属性值: New Arrivals
collection的叶子节点:名称为movie,属性{'title': 'Enemy Behind'};
collection的叶子节点:名称为movie,属性{'title': 'Transformers'};
collection的叶子节点:名称为movie,属性{'title': 'Trigun'};
collection的叶子节点:名称为movie,属性{'title': 'Ishtar'};
结点名:collection,属性字典:{'shelf': 'New Arrivals'};
结点名:movie,属性字典:{'title': 'Enemy Behind'};
结点名:type,属性字典:{};
结点名:format,属性字典:{};
结点名:year,属性字典:{};
结点名:rating,属性字典:{};
结点名:stars,属性字典:{};
结点名:description,属性字典:{};
结点名:movie,属性字典:{'title': 'Transformers'};
结点名:type,属性字典:{};
结点名:format,属性字典:{};
结点名:year,属性字典:{};
结点名:rating,属性字典:{};
结点名:stars,属性字典:{};
结点名:description,属性字典:{};
结点名:movie,属性字典:{'title': 'Trigun'};
结点名:type,属性字典:{};
结点名:format,属性字典:{};
结点名:episodes,属性字典:{};
结点名:rating,属性字典:{};
结点名:stars,属性字典:{};
结点名:description,属性字典:{};
结点名:movie,属性字典:{'title': 'Ishtar'};
结点名:type,属性字典:{};
结点名:format,属性字典:{};
结点名:rating,属性字典:{};
结点名:stars,属性字典:{};
结点名:description,属性字典:{};
           

如下为根节点具有的属性和方法:

Help on Element object:

class Element(builtins.object)
 |  Methods defined here:
 |  
 |  __copy__(self, /)
 |  
 |  __deepcopy__(self, memo, /)
 |  
 |  __delitem__(self, key, /)
 |      Delete self[key].
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(self, key, /)
 |      Return self[key].
 |  
 |  __getstate__(self, /)
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __setitem__(self, key, value, /)
 |      Set self[key] to value.
 |  
 |  __setstate__(self, state, /)
 |  
 |  __sizeof__(self, /)
 |      Size of object in memory, in bytes.
 |  
 |  append(self, subelement, /)
 |  
 |  clear(self, /)
 |  
 |  extend(self, elements, /)
 |  
 |  find(self, /, path, namespaces=None)
 |  
 |  findall(self, /, path, namespaces=None)
 |  
 |  findtext(self, /, path, default=None, namespaces=None)
 |  
 |  get(self, /, key, default=None)
 |  
 |  getchildren(self, /)
 |  
 |  getiterator(self, /, tag=None)
 |  
 |  insert(self, index, subelement, /)
 |  
 |  items(self, /)
 |  
 |  iter(self, /, tag=None)
 |  
 |  iterfind(self, /, path, namespaces=None)
 |  
 |  itertext(self, /)
 |  
 |  keys(self, /)
 |  
 |  makeelement(self, tag, attrib, /)
 |  
 |  remove(self, subelement, /)
 |  
 |  set(self, key, value, /)
 |  
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  attrib
 |      A dictionary containing the element's attributes
 |  
 |  tag
 |      A string identifying what kind of data this element represents
 |  
 |  tail
 |      A string of text directly after the end tag, or None
 |  
 |  text
 |      A string of text directly after the start tag, or None