前言
ECU诊断工作,需要实现的DTC(Diagnostic trouble code)接近500个,每个DTC的配置项基本类似。也就是说需要在ISOLAR工具上重复手动配置500个DTC。ISOLAR工具还非常的卡。
分析整个操作过程为:Excel表格读取一个DTC码-->ISOLAR工具中手动配置一个DTC-->重复500次 --> 最后生成配置文件Dem_Config.axml.
Axml文件中每一项DTC的配置内容如下,基本就是修改DTC码。
基于以上重复且有规律的工作需求,考虑使用Python脚本搞定。
注:本文章引用了一些第三方工具和文档,若有侵权,请联系作者删除!
正文
1.Python基础学习
推荐菜鸟教程:https://www.runoob.com/python3/python3-install.html。
整个学习过程推荐两到3天完成。
2.Python读取Excel表格
python操作excel主要用到xlrd和xlwt这两个库,即xlrd是读excel,xlwt是写excel的库。这里只用到xlrd模块。
2.1安装xlrd模块
命令行:pip install xlrd
2.2使用介绍
2.2.1常用单元格中的数据类型
0: empty,
1: string(text),
2:number, 3:date,
4: boolean,
5: error,
b: blank(空白)
2.2.2 导入模块
Import xlrd
2.2.3打开Excel文件读取数据
Data = xlrd.open_workbook(r’filename’)
2.2.4常用函数
Excel当中最重要的就是对book(工作簿)和sheet(工作表)的操作
1)获取book中一个工作表
table = data.sheets()[0]
#通过索引顺序获取
table = data.sheet_by_index(sheet_indx))
#通过索引顺序获取
table = data.sheet_by_name(sheet_name)
#通过名称获取
以上三个函数都会返回一个xlrd.sheet.Sheet()对象
names = data.sheet_names()
#返回book中所有工作表的名字
data.sheet_loaded(sheet_name or indx)
# 检查某个sheet是否导入完毕
2)行的操作
nrows = table.nrows
#获取该sheet中的有效行数
table.row(rowx)
#返回由该行中所有的单元格对象组成的列表
table.row_slice(rowx)
#返回由该列中所有的单元格对象组成的列表
table.row_types(rowx, start_colx=0, end_colx=None)
#返回由该行中所有单元格的数据类型组成的列表
table.row_values(rowx, start_colx=0, end_colx=None)
#返回由该行中所有单元格的数据组成的列表
table.row_len(rowx)
#返回该列的有效单元格长度
3)列的操作
ncols = table.ncols
#获取列表的有效列数
table.col(colx, start_rowx=
0
, end_rowx=
None
)
#返回由该列中所有的单元格对象组成的列表
table.col_slice(colx, start_rowx=
0
, end_rowx=
None
)
#返回由该列中所有的单元格对象组成的列表
table.col_types(colx, start_rowx=
0
, end_rowx=
None
)
#返回由该列中所有单元格的数据类型组成的列表
table.col_values(colx,start_rowx=
0
, end_rowx=
None
)
#返回由该列中所有单元格的数据组成的列表
4)单元格的操作
table.cell(rowx,colx)
#返回单元格对象
table.cell_type(rowx,colx)
#返回单元格中的数据类型
table.cell_value(rowx,colx)
#返回单元格中的数据
2.2.5代码测试
测试Excel表格
测试代码:
#!/usr/bin/env python
import
xlrd
data = xlrd.open_workbook(
r'.book.xlsx'
)
def
xlrd_read
()
:
table = data.sheets()[
0
]
#通过索引顺序获取第一个sheet1
#行操作
print(
"There are %s rows in sheet1"
%(table.nrows))
#获取该sheet中的有效行数
print(
"Return type of table.row(): "
, type(table.row(
0
)))
#返回由该行中所有的单元格对象组成的列表
print(
"Items of row 1 on shee1: "
, table.row(
1
))
#第2行列表元素
print(
"Items of row 2 on sheet1: "
, table.row_slice(
2
))
#返回由该行中所有的单元格对象组成的列表
print(table.row_types(
1
, start_colx=
0
, end_colx=
None
))
#返回由该行中所有单元格的数据类型组成的列表
print(table.row_values(
1
, start_colx=
0
, end_colx=
None
))
#返回由该行中所有单元格的数据组成的列表
print(
"Length of row 2: "
, table.row_len(
1
))
#返回该行的有效单元格长度
#列操作
print(
"There are %s columns in sheet1"
%(table.ncols))
#获取列表的有效列数
print(table.col(
0
, start_rowx=
0
, end_rowx=
None
))
#返回由该列中所有的单元格对象组成的列表
print(table.col_slice(
0
, start_rowx=
0
, end_rowx=
None
))
# 返回由该列中所有的单元格对象组成的列表
print(table.col_types(
0
, start_rowx=
0
, end_rowx=
None
))
# 返回由该列中所有单元格的数据类型组成的列表
print(table.col_values(
0
, start_rowx=
0
, end_rowx=
None
))
# 返回由该列中所有单元格的数据组成的列表
#单元格操作
print(table.cell(
1
,
1
))
# 返回单元格对象
print(table.cell_type(
1
,
1
))
# 返回单元格中的数据类型
print(table.cell_value(
1
,
1
))
# 返回单元格中的数据
def
main
()
:
xlrd_read()
if
__name__ ==
'__main__'
:
main()
测试结果
2.2.6 Python操作Excel官方网址
http://www.python-excel.org/
3.Python创建xml文件
3.1 xml语法学习
https://www.runoob.com/xml/xml-tutorial.html
3.2创建xml文件
ElementTree是python的XML处理模块,它提供了一个轻量级的对象模型。它在Python2.5以后成为Python标准库的一部分,但是Python2.4之前需要单独安装。在使用ElementTree模块时,需要import xml.etree.ElementTree的操作。
ElementTree表示整个XML节点树,而Element表示节点数中的一个单独的节点。
构建XML文件
ElementTree(tag),其中tag表示根节点,初始化一个ElementTree对象。
Element(tag, attrib={}, **extra)函数用来构造XML的一个根节点,其中tag表示根节点的名称,attrib是一个可选项,表示节点的属性。
SubElement(parent, tag, attrib={}, **extra)用来构造一个已经存在的节点的子节点。
Element.text和SubElement.text表示element对象的额外的内容属性,Element.tag和Element.attrib分别表示element对象的标签和属性。
ElementTree.write(file, encoding='us-ascii', xml_declaration=None, default_namespace=None, method='xml'),函数新建一个XML文件,并且将节点数数据写入XML文件中。
3.3 代码测试
import
xml.etree.ElementTree
as
ET
def
buildNewsXmlFile
()
:
# 设置一个新节点,并设置其标签为root
root = ET.Element(
"root"
)
# 在root下新建两个子节点,设置其名称分别为sina和chinabyte
sina = ET.SubElement(root,
"sina"
)
chinabyte = ET.SubElement(root,
"chinabyte"
)
# 在sina下新建两个子节点,设置其节点名称分别为number和first
sina_number = ET.SubElement(sina,
"number"
)
sina_number.text =
"1"
sina_first = ET.SubElement(sina,
"first"
)
sina_first.text =
"http://roll.tech.sina.com.cn/internet_all/index_1.shtml"
# 在chinabyte下新建两个子节点,设置其节点名称为number和first
chinabyte_number = ET.SubElement(chinabyte,
"number"
)
chinabyte_number.text =
"1"
chinabyte_first = ET.SubElement(chinabyte,
"first"
)
chinabyte_first.text =
"http://www.chinabyte.com/more/124566.shtml"
# 将节点数信息保存在ElementTree中,并且保存为XML格式文件
RawText = ET.tostring(root)
dom = minidom.parseString(RawText)
f = open(
r'.Test_4.axml'
,
'w'
, encoding=
'utf-8'
)
dom.writexml(f, indent=
't'
, newl=
'n'
, addindent=
't'
, encoding=
'utf-8'
)
f.close()
def
main
()
:
# xml_read()
# xml_write()
#xml_create()
buildNewsXmlFile()
if
__name__ ==
'__main__'
:
main()
4.解决问题
读取Excel表格提取需要的数据 --> 缓存数据 --> 遍历没有给数据生成xml文件 --> 合并到配置文件当值 --> 完成所有配置
#!/usr/bin/env python
import xlrd
import xml.etree.ElementTree as ET
from xml.dom import minidom
ExcelPath = r'.FileName.xlsx'
First_Dtc_RowNum = 25
Last_Dtc_RowNum = 456
DtcCodeHexStr = []
DtcCodeDemStr = []
def OpenExcel():
global DtcCodeHexStr
global DtcCodeDemStr
data = xlrd.open_workbook(ExcelPath)
table = data.sheet_by_name('DTC')
DtcCodeHexStr = table.col_values(2, start_rowx=First_Dtc_RowNum, end_rowx=Last_Dtc_RowNum)
for HexStr in DtcCodeHexStr:
int_10 = int(str(HexStr), 16)
int_10_str = str(int_10)
DtcCodeDemStr.append(int_10_str)
print(
"Type of DtcCodeHexStr = "
,type(DtcCodeHexStr))
print(
"DtcCodeHexStr = "
,DtcCodeHexStr)
print(
"Type of DtcCodeDemStr = "
, type(DtcCodeDemStr))
print(
"DtcCodeDemStr = "
, DtcCodeDemStr)
def CreatDemDtcXml():
global First_Dtc_RowNum
global Last_Dtc_RowNum
global DtcCodeHexStr
global DtcCodeDemStr
CONTAINERS = ET.Element(
"CONTAINERS"
)
for i in range(Last_Dtc_RowNum - First_Dtc_RowNum):
EcuContainrValue = ET.SubElement(CONTAINERS,
"ECUC-CONTAINER-VALUE"
)
ET.SubElement(EcuContainrValue,
"SHORT-NAME"
).text =
"DemDTC_"
+ DtcCodeHexStr[i]
ET.SubElement(EcuContainrValue,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-PARAM-CONF-CONTAINER-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemDTC"
ParameterValues = ET.SubElement(EcuContainrValue,
"PARAMETER-VALUES"
)
EcucTextualParamValue = ET.SubElement(ParameterValues,
"ECUC-TEXTUAL-PARAM-VALUE"
)
ET.SubElement(EcucTextualParamValue,
"DEFINITION-REF"
,{
"DEST"
:
"ECUC-ENUMERATION-PARAM-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemDTC/DemDTCSeverity"
ET.SubElement(EcucTextualParamValue,
"VALUE"
).text =
"DEM_SEVERITY_NO_SEVERITY"
EcuNumerivalParamValue = ET.SubElement(ParameterValues,
"ECUC-NUMERICAL-PARAM-VALUE"
)
ET.SubElement(EcuNumerivalParamValue,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-INTEGER-PARAM-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemDTC/DemDtcValue"
ET.SubElement(EcuNumerivalParamValue,
"VALUE"
).text = DtcCodeDemStr[i]
ReferenceValues = ET.SubElement(EcuContainrValue,
"REFERENCE-VALUES"
)
EcucReferenceValue = ET.SubElement(ReferenceValues,
"ECUC-REFERENCE-VALUE"
)
ET.SubElement(EcucReferenceValue,
"DEFINITION-REF"
,{
"DEST"
:
"ECUC-REFERENCE-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemDTC/DemDTCAttributesRef"
ET.SubElement(EcucReferenceValue,
"VALUE-REF"
,{
"DEST"
:
"ECUC-CONTAINER-VALUE"
}).text =
"/ETAS_Project/EcucModuleConfigurationValuess/Dem/DemConfigSet_0/DemDTCAttributes"
RawText = ET.tostring(CONTAINERS)
dom = minidom.parseString(RawText)
f = open(r'.DemDtc.axml', 'w', encoding='utf-8')
dom.writexml(f, indent='t', newl='n', addindent='t', encoding='utf-8')
f.close()
def CreatDemEventParameterXml():
global First_Dtc_RowNum
global Last_Dtc_RowNum
global DtcCodeHexStr
global DtcCodeDemStr
CONTAINERS = ET.Element(
"CONTAINERS"
)
for i in range(Last_Dtc_RowNum - First_Dtc_RowNum):
EcuContainrValue = ET.SubElement(CONTAINERS,
"ECUC-CONTAINER-VALUE"
)
ET.SubElement(EcuContainrValue,
"SHORT-NAME"
).text =
"DemEventParameter_"
+ DtcCodeHexStr[i]
ET.SubElement(EcuContainrValue,
"DEFINITION-REF"
).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter"
ParameterValues = ET.SubElement(EcuContainrValue,
"PARAMETER-VALUES"
)
EcucNumericalParamValue_0 = ET.SubElement(ParameterValues,
"ECUC-NUMERICAL-PARAM-VALUE"
)
ET.SubElement(EcucNumericalParamValue_0,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-INTEGER-PARAM-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemEventFailureCycleCounterThreshold"
ET.SubElement(EcucNumericalParamValue_0,
"VALUE"
).text =
"1"
EcucTextualParamValue_0 = ET.SubElement(ParameterValues,
"ECUC-TEXTUAL-PARAM-VALUE"
)
ET.SubElement(EcucTextualParamValue_0,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-ENUMERATION-PARAM-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemReportBehavior"
ET.SubElement(EcucTextualParamValue_0,
"VALUE"
).text =
"REPORT_BEFORE_INIT"
EcucNumericalParamValue_1 = ET.SubElement(ParameterValues,
"ECUC-NUMERICAL-PARAM-VALUE"
)
ET.SubElement(EcucNumericalParamValue_1,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-BOOLEAN-PARAM-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemEventAvailable"
ET.SubElement(EcucNumericalParamValue_1,
"VALUE"
).text =
"true"
EcucTextualParamValue_1 = ET.SubElement(ParameterValues,
"ECUC-TEXTUAL-PARAM-VALUE"
)
ET.SubElement(EcucTextualParamValue_1,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-ENUMERATION-PARAM-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemEventKind"
ET.SubElement(EcucTextualParamValue_1,
"VALUE"
).text =
"DEM_EVENT_KIND_BSW"
EcucNumericalParamValue_2 = ET.SubElement(ParameterValues,
"ECUC-NUMERICAL-PARAM-VALUE"
)
ET.SubElement(EcucNumericalParamValue_2,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-BOOLEAN-PARAM-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemFFPrestorageSupported"
ET.SubElement(EcucNumericalParamValue_2,
"VALUE"
).text =
"false"
ReferenceValues = ET.SubElement(EcuContainrValue,
"REFERENCE-VALUES"
)
EcucReferenceValue_0 = ET.SubElement(ReferenceValues,
"ECUC-REFERENCE-VALUE"
)
ET.SubElement(EcucReferenceValue_0,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-REFERENCE-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemDTCRef"
ET.SubElement(EcucReferenceValue_0,
"VALUE-REF"
, {
"DEST"
:
"ECUC-CONTAINER-VALUE"
}).text =
"/ETAS_Project/EcucModuleConfigurationValuess/Dem/DemConfigSet_0/DemDTC_"
+ DtcCodeHexStr[i]
EcucReferenceValue_1 = ET.SubElement(ReferenceValues,
"ECUC-REFERENCE-VALUE"
)
ET.SubElement(EcucReferenceValue_1,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-REFERENCE-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemOperationCycleRef"
ET.SubElement(EcucReferenceValue_1,
"VALUE-REF"
, {
"DEST"
:
"ECUC-CONTAINER-VALUE"
}).text =
"/ETAS_Project/EcucModuleConfigurationValuess/Dem/DemGeneral/DemOperationCycle_Other"
SubContainers = ET.SubElement(EcuContainrValue,
"SUB-CONTAINERS"
)
EcucContainerValu_0 = ET.SubElement(SubContainers,
"ECUC-CONTAINER-VALUE"
)
ET.SubElement(EcucContainerValu_0,
"SHORT-NAME"
).text =
"DemRbEventClass_0"
ET.SubElement(EcucContainerValu_0,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-PARAM-CONF-CONTAINER-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemRbEventClass"
ParameterValues_0 = ET.SubElement(EcucContainerValu_0,
"PARAMETER-VALUES"
)
EcucNumericalParamValue_3 = ET.SubElement(ParameterValues_0,
"ECUC-NUMERICAL-PARAM-VALUE"
)
ET.SubElement(EcucNumericalParamValue_3,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-INTEGER-PARAM-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemRbEventClass/DemRbEventBufferTime"
ET.SubElement(EcucNumericalParamValue_3,
"VALUE"
).text =
"0"
EcucNumericalParamValue_4 = ET.SubElement(ParameterValues_0,
"ECUC-NUMERICAL-PARAM-VALUE"
)
ET.SubElement(EcucNumericalParamValue_4,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-BOOLEAN-PARAM-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemRbEventClass/DemRbEventRecoverableInSameOperationCycle"
ET.SubElement(EcucNumericalParamValue_4,
"VALUE"
).text =
"1"
EcucNumericalParamValue_5 = ET.SubElement(ParameterValues_0,
"ECUC-NUMERICAL-PARAM-VALUE"
)
ET.SubElement(EcucNumericalParamValue_5,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-BOOLEAN-PARAM-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemRbEventClass/DemRbEventStatusBitStorageTestFailed"
ET.SubElement(EcucNumericalParamValue_5,
"VALUE"
).text =
"0"
EcucContainerValu_1 = ET.SubElement(SubContainers,
"ECUC-CONTAINER-VALUE"
)
ET.SubElement(EcucContainerValu_1,
"SHORT-NAME"
).text =
"DemDebounceAlgorithmClass"
ET.SubElement(EcucContainerValu_1,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-CHOICE-CONTAINER-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemDebounceAlgorithmClass"
SubContainers_1 = ET.SubElement(EcucContainerValu_1,
"SUB-CONTAINERS"
)
EcucContainerValu_2 = ET.SubElement(SubContainers_1,
"ECUC-CONTAINER-VALUE"
)
ET.SubElement(EcucContainerValu_2,
"SHORT-NAME"
).text =
"DemDebounceCounterBased"
ET.SubElement(EcucContainerValu_2,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-PARAM-CONF-CONTAINER-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemDebounceAlgorithmClass/DemDebounceCounterBased"
ReferenceValues_0 = ET.SubElement(EcucContainerValu_2,
"REFERENCE-VALUES"
)
EcucReferenceValue_2 = ET.SubElement(ReferenceValues_0,
"ECUC-REFERENCE-VALUE"
)
ET.SubElement(EcucReferenceValue_2,
"DEFINITION-REF"
, {
"DEST"
:
"ECUC-REFERENCE-DEF"
}).text =
"/AUTOSAR_Dem/EcucModuleDefs/Dem/DemConfigSet/DemEventParameter/DemDebounceAlgorithmClass/DemDebounceCounterBased/DemDebounceCounterBasedClassRef"
ET.SubElement(EcucReferenceValue_2,
"VALUE-REF"
, {
"DEST"
:
"ECUC-CONTAINER-VALUE"
}).text =
"/ETAS_Project/EcucModuleConfigurationValuess/Dem/DemConfigSet_0/DemDebCntClass_U127_D127"
RawText = ET.tostring(CONTAINERS)
dom = minidom.parseString(RawText)
f = open(r'.DemEventParameter.axml', 'w', encoding='utf-8')
dom.writexml(f, indent='t', newl='n', addindent='t', encoding='utf-8')
f.close()
def main():
OpenExcel()
CreatDemDtcXml()
CreatDemEventParameterXml()
if __name__ == '__main__':
main()
5.总结
每个人在处理Excel数据的时候,如果发现是重复且有规律的工作,都可以考虑使用Python来提高效率。当然,Python的功能还有很多很多,把基本知识学好,后面遇到什么就学什么,有目的的去学要快很多。
End
原文始发于微信公众号(汽车电子嵌入式):Python给工作减负--读Excel文件生成xml文件
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论