目標產出
Output.xml
<EDC>
<object_id>OBJ_ID</object_id>
<product_id>PROD_ID</product_id>
<eqp_id>EQP_ID</eqp_id>
<owner></owner>
<recipe_id>RECIPE_ID</recipe_id>
<operation>OPER</operation>
<cldate>2022-11-16</cldate>
<cltime>23:25:39</cltime>
<datas>
<iary>
<item_name>illuminance_B_NA</item_name>
<item_type>X</item_type>
<item_value>751</item_value>
</iary>
<iary>
<item_name>illuminance_B_PL</item_name>
<item_type>X</item_type>
<item_value>2233</item_value>
</iary>
<iary>
<item_name>illuminance_U_NA</item_name>
<item_type>X</item_type>
<item_value>623</item_value>
</iary>
<iary>
<item_name>illuminance_U_PL</item_name>
<item_type>X</item_type>
<item_value>2123</item_value>
</iary>
</datas>
</EDC>
程式說明
基本ElementTree 操作
import xml.etree.ElementTree as ET
XML = ET.ElementTree() # 建立 ElementTree 物件
EDC = ET.Element('EDC') # 建立 Element 物件
XML._setroot(EDC) # 設定ElementTree XML 的根節點為EDC
_object_id = ET.SubElement(EDC, 'object_id') # 建立 SubElement 物件 - object_id
# print(ET.dump(XML)) # print Element / ElementTree 內容
XML.write("Output.xml") # 輸出檔案
output.xml
<EDC><object_id /></EDC>
write() parameter - short_empty_elements
XML.write("Output.xml") → XML.write("Output.xml", short_empty_elements=False)
output.xml
<EDC><object_id></object_id></EDC>
換行與縮排 - pretty_xml
import xml.etree.ElementTree as ET
def pretty_xml(element, indent, newline, level=0):
if element: # 判断element是否有子元素
if (element.text is None) or element.text.isspace(): # 如果element的text没有内容
element.text = newline + indent * (level + 1)
else:
element.text = newline + indent * \
(level + 1) + element.text.strip() + \
newline + indent * (level + 1)
# else: # 此处两行如果把注释去掉,Element的text也会另起一行
# element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * level
temp = list(element) # 将element转成list
for subelement in temp:
# 如果不是list的最后一个元素,说明下一个行是同级别元素的起始,缩进应一致
if temp.index(subelement) < (len(temp) - 1):
subelement.tail = newline + indent * (level + 1)
else: # 如果是list的最后一个元素, 说明下一行是母元素的结束,缩进应该少一个
subelement.tail = newline + indent * level
pretty_xml(subelement, indent, newline,
level=level + 1) # 对子元素进行递归操作
return element
XML = ET.ElementTree() # 建立 ElementTree 物件
EDC = ET.Element('EDC') # 建立 Element 物件
XML._setroot(EDC) # 設定ElementTree XML 的根節點為EDC
_object_id = ET.SubElement(EDC, 'object_id') # 建立 SubElement 物件 - object_id
# 對root Element 進行縮排與換行
EDC = pretty_xml(EDC, " ", "\n") # 縮排使用兩個空格
# EDC = pretty_xml(EDC, "\t", "\n") # 縮排使用 tab
XML.write("Output.xml", short_empty_elements=False) # 輸出檔案
output.xml
<EDC>
<object_id></object_id>
</EDC>
完整程式碼
import xml.etree.ElementTree as ET
import traceback
import datetime
def item2XML(xml_filename, object_id, product_id, eqp_id, owner, recipe_id, operation, cldate, cltime, datas):
# elemnt为传进来的Elment类,参数indent用于缩进,newline用于换行
def pretty_xml(element, indent, newline, level=0):
if element: # 判断element是否有子元素
if (element.text is None) or element.text.isspace(): # 如果element的text没有内容
element.text = newline + indent * (level + 1)
else:
element.text = newline + indent * \
(level + 1) + element.text.strip() + \
newline + indent * (level + 1)
# else: # 此处两行如果把注释去掉,Element的text也会另起一行
# element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * level
temp = list(element) # 将element转成list
for subelement in temp:
# 如果不是list的最后一个元素,说明下一个行是同级别元素的起始,缩进应一致
if temp.index(subelement) < (len(temp) - 1):
subelement.tail = newline + indent * (level + 1)
else: # 如果是list的最后一个元素, 说明下一行是母元素的结束,缩进应该少一个
subelement.tail = newline + indent * level
pretty_xml(subelement, indent, newline,
level=level + 1) # 对子元素进行递归操作
return element
try:
XML = ET.ElementTree() # 建立 ElementTree 物件
EDC = ET.Element('EDC') # 建立 Element 物件
XML._setroot(EDC) # 設定ElementTree XML 的根節點為EDC
_object_id = ET.SubElement(EDC, 'object_id')
_object_id.text = object_id
_product_id = ET.SubElement(EDC, 'product_id')
_product_id.text = product_id
_eqp_id = ET.SubElement(EDC, 'eqp_id')
_eqp_id.text = eqp_id
_owner = ET.SubElement(EDC, 'owner')
_product_id.text = product_id
_recipe_id = ET.SubElement(EDC, 'recipe_id')
_recipe_id.text = recipe_id
_operation = ET.SubElement(EDC, 'operation')
_operation.text = operation
_cldate = ET.SubElement(EDC, 'cldate')
_cldate.text = cldate
_cltime = ET.SubElement(EDC, 'cltime')
_cltime.text = cltime
_datas = ET.SubElement(EDC, 'datas')
for data in datas:
_iary = ET.SubElement(_datas, 'iary')
_item_name = ET.SubElement(_iary, 'item_name')
_item_name.text = data['item_name']
_item_type = ET.SubElement(_iary, 'item_type')
_item_type.text = data['item_type']
_item_value = ET.SubElement(_iary, 'item_value')
_item_value.text = str(data['item_value'])
EDC = pretty_xml(EDC, " ", "\n")
XML.write(xml_filename,
short_empty_elements=False) # 寫入檔案
return True
except Exception:
print(traceback.format_exc())
return False
if __name__ == "__main__":
object_id = "OBJ_ID"
product_id = "PROD_ID"
eqp_id = "EQP_ID"
owner = "OWNER"
recipe_id = "RECIPE_ID"
operation = "OPER"
cldate = datetime.datetime.now().strftime("%Y-%m-%d")
cltime = datetime.datetime.now().strftime("%H:%M:%S")
datas = [
{"item_name": "illuminance_B_NA", "item_type": "X", "item_value": 751},
{"item_name": "illuminance_B_PL", "item_type": "X", "item_value": 2233},
{"item_name": "illuminance_U_NA", "item_type": "X", "item_value": 623},
{"item_name": "illuminance_U_PL", "item_type": "X", "item_value": 2123},
]
result = item2XML("Output.xml", object_id, product_id, eqp_id,
owner, recipe_id, operation, cldate, cltime, datas)
print(f"IsSuccess: {result}")
參考文獻