xml是一种标记语言,简单、方便在任何程序中读写数据,使其成为一种广泛使用的数据交换语言。
一、解析xml:element Tree
(一)访问某些URL时,常返回带有xml信息的str,解析成xml后,才可操作使用相关数据。
(二)对.xml文件进行读写及相关数据操作,需要对xml文件进行解析。
P.S.:解析操作的过程是在内存中完成的,若需要将数据保存,需要写入文件。不同解析方式,有不同的写入方式。
#------------------ 使用元素树方式,解析xml-------------------------------- # 导入XML模块 from xml.etree import ElementTree as ET #### 1、直接解析str为xml对象,获得根节点 ,相关操作后,存入文件#### #### 1.1 在内存中直接将url返回的str转换成xml对象,返回根节点,相关操作后,打开文件,写入保存 # root = ET.XML(ret_str) # type(root):<class 'xml.etree.ElementTree.Element'> # 解析后的内容及相关操作,需要写入文件才能保存 # with open('first_xml.xml','wb') as f: # f.write(ET.tostring(root)) # ET.tostring() 的返回结果是bytes类型 #### 1.2 解析xml文件,获得根节点 ,相关操作后,xml对象直接写入文件#### # # 方式一:先加载文件,再解析文件字符串成xml,并获得根节点 # str_xml = open('first_xml.xml','r').read() # root = ET.XML(str_xml) # # 相关操作后,需要将修改写入文件 # tree = ET.ElementTree(root) # tree.write('first_xml.xml',encoding='utf-8') # # # 方式二:直接解析文件成xml对象,再获取xml对象的根节点 tree = ET.parse('first_xml.xml') root = tree.getroot() # # 相关操作后,需要将修改写入文件 # tree.write('first_xml.xml',encoding='utf-8')
二、节点操作
(一)对于节点node,可使用node.tag、node.attrib、node.text分别获得节点的标签名、属性、文本。
(二)node.set(’key‘,’value‘)增加节点属性key=value,del node.attrib['name'] 删除node节点的'name'属性。
(三)node.getchildren() 取node全部子节点,列表形式;node.iter(’name') 取指定子节点‘name',得到的是一个含有全部’name'子节点的生成器。
取指定子节点,还可以使用:node.findall(’name‘)、node.find(’name'),此时直接取得节点,占内存较大。
(四)添加子节点,可直接使用:ET.subelement(father,son);也可以son = ET.element() 新建节点son后,father.append(son)。
(五)删除子节点:直接使用:father.remove(son)
#--------------------------对root进行操作-------------------------------- #------------------------------------------------------------------------- # # 以根节点为例: # # --------------------------3.1获取节点标签、属性和文本 # print(root.tag) # print(root.attrib) # 无属性时:{} # print(root.text) # # ----------------------------------3.2添加、删除属性 # # 添加属性 # root.set('name','lucy') # root.set('age','6') # # print(root.attrib) # # 删除属性 # del root.attrib['age'] # # # -----------------------------3.3查看子节点------------ # # # 3.3.1 获得全部子节点 # # 返回子节点列表,列表每一个元素又都是一个节点 # all_son_of_root = root.getchildren() # type(all_son_of_root):<class 'list'> # for eve_son in all_son_of_root: # print(eve_son, eve_son.text) # for son_of_son in eve_son: # print(son_of_son.text) # # 3.3.2 获取指定的子节点 # #node.iter()获取全部‘list’节点 # for node_of_page in root.iter('list'): # #获取‘list’节点中的‘page’节点 # for node_of_page in node_of_page.iter('page'): # # 修改节点文本 # new_page = int(node_of_page.text) + 1 # node_of_page.text = str(new_page) # print(node_of_page.text) # # # 获取指定节点之 # print(type(root.iter('list'))) # 返回全部符合条件的生成器,推荐使用,节省内存 # print(type(root.findall('list'))) # 返回全部符合条件的列表 # print(type(root.find('list'))) # 仅返回符合条件的一个节点 #--------------------------3.4添加、删除节点 # 3.4.1添加节点 # 节点标签名字之间不能有空格,如"yes or no"会出现错误的,“yes_or_no"才是正确的 # 方式一:新建节点,添加至指定父节点 # new_son_of_root = ET.Element('yes_or_no',attrib={'y':'好的','n':'不好吧'}) # 创建新节点,添加标签和属性 # new_son_of_root.text = '添加文本' # 为创建的节点添加文本 # root.append(new_son_of_root) # 将新节点加入根节点 # 方式二:父节点下直接添加子节点 # ET.SubElement(root,'直接添加儿子') # 3.4.2删除节点 # # 找到需要删除的节点 # for eve in root.iter('yes_or_no'): # # 删除指定节点 # root.remove(eve) # #添加孙子节点 # new_node= ET.Element('writer',attrib={'school':'btbu'}) # father_node = root.find('list') # 查找指定节点 # father_node.append(new_node) #
三、优雅打印:缩进和换行
使用elemnetTree方式解析xml,简单、高效,但是打印时代码可读性差,没有换行和缩进。
使用dom方式解析xml,虽然功能少、效率低,但是xml.dom.minidom模块,可以优雅显示代码。
若提高代码打印时的可读性,可在打印时,进行自定义操作:
1、将elemnetTree解析、操作后的root
2、ET.tostring(root)将根节点root转成含xml信息的bytes
3、minidom.parseString(bytes)将含xml信息的bytes转成dom对象***
4、***.toprettyxml()将***转成换行、缩进的字符串,但含有多余空行
5、使用正则表达式去掉多余空行
# #------------------------------------------------优雅打印,增强可读性 # # 根节点——》bytes——》dom——》str # # from xml.etree import ElementTree as ET # from xml.dom import minidom # import re # # ---------取得待处理xml的根节点 # # 元素树方式打开文件 # tree = ET.parse('first_xml.xml') # # 获得根节点 # root = tree.getroot() # # #----------将xml对象解析成str # # 由根节点,得到包含xml全部信息的bytes # root_bytes = ET.tostring(root,encoding='utf-8') # # 由bytes,得到dom对象 # reparsed_to_dom = minidom.parseString(root_bytes) # # 由dom对象,得到包含xml全部信息的str # pretty_str = reparsed_to_dom.toprettyxml(indent='\t') # # #------------使用正则表达式去掉多余空行 # # 使用正则去掉空行 # new_pretty_str = re.sub('\n[\s|]*\n','\n',pretty_str) # # # --------------优雅打印 # print(new_pretty_str) # # print(pretty_str)
P.S.:
附件:使用的实例‘first_xml.xml’文件代码
<info name="lucy"> <intro>Book message</intro> <list id="001"> <head>bookone</head> <name>python check</name> <number>001</number> <page>209</page> <writer school="btbu" /> <writer school="btbu" /></list> <list id="002"> <head>booktwo</head> <name>python learn</name> <number>002</number> <page>309</page> </list> <test_add_node n="不好吧" y="好的">添加文本</test_add_node> <直接添加儿子 /> </info>
浙公网安备 33010602011771号