继上一篇介绍了xml实际应用,包括对采集数据如何打包、入库、解析。本文继续结合实际需求详细介绍xml数据包如何修改。
业务场景:实际数据上传过程中,为了保证数据的准确性、及时性及统一性,一般在原始数据库到数据解析库设置数据转换处理流程。针对xml数据包内容的变更(设备更换、采集点增加等),后台如何对xml指定位置插入、修改、删除节点;针对同一个采集对象,多个网关转发数据包的合并。
ElementTree模块提供多种修改xml的方法
1、ElementTree.write("xmlfile") #更新xml文件
2、Element.append():为当前的element添加子元素
3、Element.set(key,value):为当前的element的key属性设置value值
4、Element.remove(element):删除为element的节点
测试xml文件
<root encoding="utf-8">
<data operation="report">
<meter name="000000000001">
<function name="000000000001-1090">890</function>
</meter>
<meter name="000000000002">
<function name="000000000002-1090">198</function>
</meter>
<meter name="000000000003">
<function name="000000000003-1090">500</function>
</meter>
</data>
</root>
xml修改基本操作演示
# 导入模块
import xml.etree.ElementTree as ET
# 读取将被修改的文件并获取根节点
tree =ET.parse("new.xml")
root=tree.getroot()
#创建新节点sub_new,添加属性和数据,并将其设置为root的子节点
sub_new=ET.Element("sub_new")
sub_new.attrib={"name":"000000000004"}
sub_new.text="new element"
root.append(sub_new)
#修改sub1的attribute属性,比如name更新为新的编号
sub1=root.find("sub1")
sub1.set("attribute","new attribute")
#修改sub2的数据
sub2=root.find("sub2")
sub2.text="new value"
#删除子节点sub3
sub3=root.find("sub3")
root.remove(sub3)
tree.write("new.xml")
场景一:指定位置插入、修改、删除节点
代码部分:
import xml.etree.ElementTree as ET
#指定位置插入节点
tree =ET.parse("new_test.xml")
root=tree.getroot()
#获取data下所有的节点
lst=root.findall("data")
lst1=lst[0].findall("meter")
# 创建一个新节点meter_new
sub_new=ET.Element("meter_new")
sub_new.attrib={"name":"000000000004"}
#将function_new设置为meter_new的子节点,添加属性和数据
sub_new1=ET.SubElement(sub_new,"function_new")
sub_new1.attrib={"name":"000000000004-1090"}
sub_new1.text="90"
#指定位置插入
lst1.insert(0,sub_new)
print(lst1)
#删除data节点历史数据
sub=root.find("data")
root.remove(sub)
#创建新节点data
data=ET.SubElement(root,"data")
#添加节点
[data.append(i) for i in lst1]
#写入更新xml
tree.write("new_test1.xml")
结果:
<root encoding="utf-8">
<data>
<meter_new name="000000000004">
<function_new name="000000000004-1090">90</function_new>
</meter_new>
<meter name="000000000001">
<function name="000000000001-1090">890</function>
</meter>
<meter name="000000000002">
<function name="000000000002-1090">198</function>
</meter>
<meter name="000000000003">
<function name="000000000003-1090">500</function>
</meter>
</data>
</root>
场景二:同一时刻多个数据xml合并
合并xml结构如下
<root encoding="utf-8">
<data operation="report">
<meter name="xxxxxxxxxx">
<function name="xxxxxxx-1090">数据</function>
</meter>
</data>
</root>
代码部分:
import os
import xml.etree.ElementTree as ET
def xml_combine(xml_dir):
# 创建根节点,根据xml结构样式设置即可
root=ET.Element("root")
tree = ET.ElementTree(root)
#创建子节点data
data = ET.SubElement(root, "data")
xml_data = [i for i in os.listdir(xml_dir)]
xml_list=[]
for i in range(len(xml_data)):
# 读取将被修改的文件并获取根节点
tree_ = ET.parse(xml_dir+"\{0}".format(xml_data[i]))
root_ = tree_.getroot()
# 获取data下所有的节点
lst = root_.findall("data")
lst1 = lst[0].findall("meter")
#meter节点合并成一个列表
xml_list.extend(lst1)
#添加节点
[data.append(i) for i in xml_list]
# 写入更新xml
tree.write("xml_combine.xml")
if __name__ == '__main__':
xml_dir = r"D:\myProjectfile\xml_parse\xml"
xml_combine(xml_dir)
小结:同一监测对象,由于采集设备更换(配置编号的变更),导致历史数据和当前数据的断层,因此后台数据仓库ETL过程需设置后处理环节对历史数据更新(考虑变更点初始值的设置),从而重塑监测对象完整时间序列,统一数据统计口径,减少冗余支路数据。
本文分享自 Python数据分析实例 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!