之前做odoo的时候,遇到一个需求,就是通过自定义视图字段的显示名称和显示属性invisible,然后用了一个最直接,最笨的方法,就是通过字符串的定位,截取,拼接,修改视图的arch_base,就是视图结构的字符串,然后想通过python的某个库来实现xml的解析,去达到目的,这次使用的是xml.etree.ElementTree,如果有看法,请评论,互相学习:
from xml.etree import ElementTree as ET
from xml.etree.ElementTree import Element
# view.arch_base是一个xml字符串,视图的结构
# 将xml字符串转化成xml对象
# 如果在python2.x下,会报编码错误,可以加上这几行代码
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
# 在python3.x下则不会报错
ele_obj = ET.fromstring(view.arch_base)
# findall查询根节点下的所有直系子节点,find查询根节点下的第一个直系子节点
nodes = ele_obj.findall('field')
# 遍历nodes,可以得到每个节点node
# 通过get方法获取这个节点中的属性值,key就是属性名称,如name,id等
value = node.get(key)
# 通过attrib获取由节点中的所有属性及值组成的一个字典
dic_att = node.attrib
# 判断某个属性是否存在节点中
attr = 'name'
if attr in node.attrib:
print('yes')
if node.get(attr) == 'name':
print('yes')
# 获取节点的标签名称
tag_name = node.tag
# 修改节点的属性
node.set('name', 'test')
# 获取节点下的所有子节点,直系和非直系
# 也可以指定特定的节点,加一个参数tag='field',即可获取所有的标签为field的所有子节点
list_node = tag.iter()
list_node = tag.iter(tag='field')
# 目前我知道的判断是否存在子节点,需要转化,再判断长度
length = len(list(list_node))
注意:
# 获取某个节点,判断这个节点是否存在,最好通过get()来判断是否存在
# 不要通过if,if是判断这个节点是否存在子节点
# 创建一个新的节点,假设这个新的节点没有子节点,那么生成的形式是这样的
# <field name="hello" money="200000"/>
ele = Element('field', {"name":"hello","money":"200000"})
# 向一个节点中添加节点,这样会添加到node中的最后位置
node.append(ele)
# 将处理后的xml对象转化成xml字符串
# 默认的encoding是字节流,method默认是xml
str_xml = ET.tostring(ele_obj, encoding='unicode', method='xml')
# 对于删除节点,remove(节点实例element),通过find,findall获取到的节点,可以直接删除或者遍历删除,
# remove只能删除直接子级或者自己,孙子级会报错找不到对应的节点,对于iterfind返回值是迭代器的,要转化成list才能用remove
# iterfind通过path定位,来查找直系子级或者非直系子级
tags.iterfind(path='.//field[@name="name"]')