简介:ISO 22900-2:2017 D-PDU API中英文对照翻译文档,面向汽车诊断软件工程师、测试员及MVCI协议模块开发人员,用于快速理解道路车辆模块化通信接口中诊断协议数据单元(D-PDU)的API规范。该文档由DeePL机器翻译生成,采用中英文对照排版,便于逐句对照阅读标准原文,尤其适合需要掌握D-PDU与ODX运行时数据交互逻辑的读者。资源包为单个docx文件,约760KB,内含标准全文的完整翻译与原文对照,覆盖范围、规范性引用、术语定义以及D-PDU API详细技术条款;目前已有1864人学习浏览。出于双语对照的优势,读者可直接参考中文理解请求转换、错误处理、数据编码、安全性和实时性等关键设计要点,同时可根据英文原文核对专业术语,显著降低阅读门槛。对于汽车诊断工具开发、ECU测试和实验室验证工作,这份资料是一份便于查阅且实用的标准参考。
1. 拿到ISO 22900-2-2017 D-PDU-API标准,先别急着用DeePL整本直出
ISO 22900-2-2017 D-PDU-API是诊断设备到车辆ECU之间访问数据的关键接口规范,开发诊断仪和网关的工程师几乎每天都会和它的C语言函数原语、错误码和数据结构打交道。在很多项目里,中文版只是内部口头翻译,真要形成书面资料,最常见的动作是把PDF里的英文条款复制到DeePL里面。结果常常是翻译结果能看但不敢用:函数名被改成了中文、PDU_ID变成“PDU标识”、shall和should混成一体。这篇文章不讲“哪款软件能一键翻译”,而是站在要长期维护双语文档的工程师视角,把ISO 22900-2-2017 D-PDU-API标准按条款拆分成可管理的翻译单元,再配合DeePL API和一个小型流水线,做出一份术语一致、可校验、可更新的中英对照翻译。
2. 拆解ISO 22900-2 D-PDU-API标准:先分片再交给DeePL
ISO 22900-2-2017不是一本纯文字规范。它里面既有自然语言描述,也夹杂大量C头文件风格的代码块和表格式的枚举定义。直接整体处理会让DeePL把代码和正文混在一起,丢失标识符的大小写或类型后缀。所以第一步不是翻译,而是把标准文本拆成不同“待遇”的片段。
2.1 标准正文里能直接翻译和不能直接翻译的部分
先通读一遍目录,明确ISO 22900-2 D-PDU-API到底由哪几块组成。条款4通常是缩略语和术语定义,条款5到条款7是服务原语和API函数说明,后面还会带大量C语言结构体、回调函数原型和错误处理代码。按我的习惯,它们大致落在三个桶里:
第一类是条款正文和表注,里面是连贯的英文句子,适合交给DeePL整段翻译。第二类是代码块和示例,包括函数原型、结构体定义、宏定义以及参数列表。这些必须原样保留,不能参与翻译。第三类是术语和错误码表,表的单元格里既有固定标识符,也有描述性文本。翻译时标识符留在英文,描述再转成中文。
下面这张表格是拆分时的通用参考:
| 片段类型 | 典型样例 | 是否交给DeePL | 处理方式 |
|---|---|---|---|
| 条款正文 | D-PDU API provides an interface between application and protocol layer | 是 | 保留段落顺序翻译 |
| 术语定义 | Protocol Data Unit (PDU) | 是,保留缩写 | PDU和PDU Unit按术语表处理 |
| 函数原型 | uint16 PDU_GetStatus(PDU_ID_T pdu_id); | 否 | 原样保留 |
| 结构体定义 | typedef struct { uint16 size; uint8* data; } PDU_DATA_T; | 否 | 原样保留 |
| 错误码表 | PDU_ERR_INVALID_PDU_ID: Indicates an invalid PDU ID. | 描述翻译 | PDU_ERR_INVALID_PDU_ID不译 |
完成这个分类的下一步,是把PDF按“能翻译/不能翻译”物理拆开,否则后续处理无从下手。很多工程师在这里犯的第一个错就是拿网页版DeePL直接粘贴,网页版虽然支持全文翻译,但对输入长度和格式敏感,粘贴大段带代码的PDF文本时还会丢缩进。所以切片这一步省不得。
2.2 按条款号切分段落,让DeePL上下文更稳
DeePL处理连续文本时,前后的指代关系越完整,译文越通顺。但标准文本动辄几十页,一次性翻译超过上下文窗口后,后面的部分容易出现“指代丢失”。常见做法是按条款号把文本切成块,DeePL每次只处理一个带完整编号的片段。
如果是PDF,我一般先用pdftotext -layout ISO_22900-2-2017.pdf iso.txt保持原始缩进。通过正则把^[0-9]+(\.[0-9]+)*开头的行作为片段边界,把正文切分成若干临时文件。这里有一个简单示例:
awk '/^[0-9]+\.[0-9]*(\.[0-9]+)*[[:space:]]/{if (buf != "") print buf > "seg_" n ".txt"; n++; buf=$0; next} {buf = buf ORS $0} END {if (buf != "") print buf > "seg_" n ".txt"}' iso.txt这条命令把以条款编号起头的行视为新分片起点,之前累积的文本输出到seg_N.txt。注意在ISO 22900-2的实际PDF里,目录中的数字编号会和正文重复。所以运行前最好先粗略看一遍行号范围,过滤目录区段,避免切出大量无意义的小文件。切完后检查每个seg_*.txt的大小,小于3千字节的片段可以考虑和前一片合并。
另一个容易被忽略的问题是分片边界上的标点。如果条款正文最后一段在PDF里被拆成两页,pdftotext会把它切进两个连续片段里,DeePL分别翻译时会把同一个句子翻译成两个不同风格的结果。解决方法是让每条片段在段落边界处切断,而不是在任意行号处硬切。给awk脚本加一个“下行是空行才输出”的条件,就能把片段边界对齐到自然段。
2.3 用占位符保护API标识符
分片后还不能直接翻译。片段里残留的代码、函数名和错误码仍然可能在中间位置被打乱。我在实践中会对关键标识符做一次“占位符替换”,把PDU_ID_T、PDU_Create、PDU_MODULE_ID_T这类名称替换成__PH1__、__PH2__这样的安全串。这样DeePL不管怎么调整语序,占位符始终不会被改写。翻译完成后,再用映射表把占位符替换回去。
占位符要避开标准里不会出现的字符串,比如__PDU_PH_01__。替换时可以用正则整体替换\bPDU_[A-Z0-9_]+为__PH_xx__。此步骤和代码块的提取放在一起,后面的翻译脚本会直接复用这套逻辑。
提示:不要在占位符里使用
{}或<>,DeePL有时会把带尖括号的内容当成XML标签处理,导致结果里出现多余换行。
3. 用DeePL API搭ISO 22900-2双语文档生成流水线
手动一段段贴到网页版翻译ISO 22900-2很费时间,也不方便保持术语表统一。更可控的方式是直接调用DeePL API。这样除了能保留占位符,还可以把翻译、断言检查、输出Markdown三步固化成一个命令。
3.1 准备API访问和最小参数设置
先去DeePL开发者后台申请API密钥,国内个人开发者通常使用免费额度测试。把密钥放到环境变量DEEPL_API_KEY里,本地安装官方Python库:
pip install deepl然后确认账号支持的API区域。DeePL的API地址有api-free.deepl.com和api-api.deepl.com之分,免费版用前者,付费版用后者。这个区域参数在初始化客户端时必须显式配置,否则会出现认证失败。库的常用初始化方式是:
import os import deepl auth_key = os.environ["DEEPL_API_KEY"] server_url = "https://api-free.deepl.com/v2" # 免费版 translator = deepl.Translator(auth_key, server_url=server_url)server_url不是调试用的可有可无参数。串到付费版地址时,即便密钥有效也会返回信用额度不足或401。参数传完之后,建议先用一个短字符串调用translator.translate_text,确认连通性再批量跑。免费版对单次请求长度有限制,ISO 22900-2的单个分片如果超过几千字符,接口会返回文本过长错误,这也是为什么上一章要把片段控制在300到500词之间。
3.2 一个保留代码块的批量翻译脚本
下面脚本读入前一步生成的seg_*.txt,先对每个文件做代码块提取和标识符占位符替换,再调用DeePL把剩余文本翻译成中文,最后把代码块还原到原位置,输出zh_*.md。核心逻辑如下:
import re import os import glob import deepl translator = deepl.Translator(os.environ["DEEPL_API_KEY"], server_url="https://api-free.deepl.com/v2") CODE_PATTERN = re.compile(r"(:?^|\n)((?:[ \t]{2,}[^\n]+\n)+)", re.M) PH_MAPPING = {} def protect_code_block(text): group = [] def keep(m): ph = f"__PDU_PH_{len(group):03d}__" group.append(m.group(2)) PH_MAPPING[ph] = m.group(2) return m.group(1) + ph return CODE_PATTERN.sub(keep, text), group def restore(text): for ph, original in sorted(PH_MAPPING.items(), key=lambda x: -len(x[0])): text = text.replace(ph, original) return text for seg_file in sorted(glob.glob("seg_*.txt")): with open(seg_file, encoding="utf-8") as f: src = f.read() text, code_blocks = protect_code_block(src) # 二次保护:下划线连接的大写标识符 text = re.sub(r"\bPDU_[A-Z0-9_]+\b", lambda m: f"__PDU_SYM_{len(PH_MAPPING):03d}__", text) result = translator.translate_text( text, target_lang="ZH-HANS", formality="prefer_less", # 技术文档少用“您”,贴近操作描述 tag_handling="xml", ) translated = restore(result.text) out_name = seg_file.replace(".txt", ".zh.md") with open(out_name, "w", encoding="utf-8") as f: f.write(translated)这段脚本最关键的是protect_code_block函数。它用正则匹配到连续两空格缩进的行,先把整块代码存到列表,再用__PDU_PH_000__一类占位符替换。DeePL会把这些占位符当作普通单词保留到译文里,而不会给它们加入空格或改成中文。后面restore再把原始代码块回填。
translate_text的两个参数值得单独说:target_lang="ZH-HANS"指定简体中文,如果你的读者使用繁体,改成ZH-HANT;formality="prefer_less"告诉DeePL尽量不用“您”这类敬语。ISO 22900-2里大量出现“shall”,用默认设置时容易被译成“将”,我习惯在翻译后统一做一次shall替换,后面第四章会专门讲。
3.3 调用之后立即做的三项自检
翻译脚本跑完并不代表结束。第一,检查输出文件里是否残留__PDU_开头的占位符,只要有就说明还原失败,需要用原始映射重新替换。第二,检查处理过的文件里英文字符占比,DeePL会把PDU误译成中文的情况不多,但偶尔会把PDU写成“PDU”。如果大量出现,说明保护正则没有覆盖全。第三,用diff对比源文件里的代码行和输出文件里的代码行,确保代码块还原后没有增删字符。这三项都可以在脚本末尾自动完成,但第一次先手动跑一遍,熟悉误报的形态。
4. D-PDU-API翻译中术语不一致的典型坑与质量控制
ISO 22900-2里的术语不像普通软件文档那样可以随意翻译。PDU、D-PDU API、module、slot这几个词在中英文语境下都有对应关系。术语一旦失控,函数注释、错误码表、API描述都会互相打架,之后的团队评审会一直纠缠“这处为什么叫模块、另一处叫组件”。这一章解释如何让DeePL在翻译时就带上术语约束,并在翻译后用脚本兜住剩余的不一致。
4.1 把中英术语表做成DeePL Glossary
DeePL官方的术语表功能可以直接在API请求里指定一个由源语言和译文对组成的XML或CSV词典。常见做法是新建一个CSV,前两行分别写英文和中文,之后每行放一对术语。对ISO 22900-2 D-PDU-API,我的术语表里至少包含:
| 英文 | 中文 |
|---|---|
| PDU | PDU |
| D-PDU API | D-PDU API |
| protocol layer | 协议层 |
| application layer | 应用层 |
| shall | 应 |
| may | 可以 |
| should | 宜 |
| error code | 错误码 |
| device | 设备 |
| module | 模块 |
注意前三行里PDU和D-PDU API的译文故意保留英文。原因不难理解:在代码上下文和工程口语里,直接说“PDU”比说“协议数据单元”更不容易产生歧义。术语表建成后,上传并获取一个glossary_id:
glossary = translator.create_glossary( "iso22900-2", source_lang="EN", target_lang="ZH-HANS", entries={"PDU": "PDU", "D-PDU API": "D-PDU API", "shall": "应"} )后续翻译请求里加一个参数glossary=glossary,DeePL就会优先使用这些配对。和第三章的占位符保护相比,Glossary解决的是自然语言层面的用词统一,占位符解决的是代码层面的绝对保留,两者不冲突。
4.2 对数字、宏和错误码做自动校验
术语表并不能锁死一切。ISO 22900-2的错误码表格里经常出现0x80010003L这样的数值,翻译时容易被DeePL拆开或丢失末尾L。我习惯在批量翻译后用一个正则脚本扫描译文,统计数字和标识符的偏差。
import re def check_symbols(src_path, tgt_path): sym_re = re.compile(r"\bPDU_[A-Z0-9_]+\b|0x[0-9A-Fa-f]+L?|\b[A-Za-z_][A-Za-z0-9_]*(?=\s*\()") src = open(src_path, encoding="utf-8").read() tgt = open(tgt_path, encoding="utf-8").read() src_syms = set(sym_re.findall(src)) tgt_syms = set(sym_re.findall(tgt)) missing = src_syms - tgt_syms for m in sorted(missing): print("MISSING:", m)这个检查脚本不需要做分词,只需要把函数名、十六进制数和错误码挑出来。PDU_ERR_INVALID_PDU_ID如果少了下划线或者结尾少一个字母,它就不在tgt_syms里,会立刻被报告。注意它也会把正文里的普通英文单词当成符号,所以跑完之后要过滤掉那些在术语表里已经正常出现的中文,只保留明显的函数名和十六进制常量。
4.3 从DeePL译文里纠出最影响阅读的三种错误
即使有了术语表和占位符,仍有三类错误会频繁出现在ISO 22900-2的中文版中。第一种是shall/should。ISO 22900系列里shall都表示强制性要求,DeePL有时译成“要”,有时译成“将会”,不统一。在术语表里把shall固定成“应”之后,剩余工作就是全局搜索“将”和“要”,逐个判断是否由shall产生。
第二种是module和slot的译法。D-PDU module在硬件描述里指诊断模块,slot在配置表里表示插槽。把module统一译成“模块”,把slot统一译成“插槽”,不要因为句子顺就到了“设备槽位”或“卡槽”。第三种是表格内嵌的英文注释。表格单元格里的(see 7.2.3)会被DeePL翻译成“(见 7.2.3)”,但该标准本身不常使用全角括号,所以中文译文反而会出现半角全角混用。
对于这三类问题,我一般不会在DeePL译文基础上手动逐处改,而是放到后期用正则统一替换。比如should转成“宜”、shall转成“应”、0x后端带空格的十六进制数修正回来。为了保持术语稳定,替换规则也应当写进更新脚本里,而不是靠编辑器一次一次地查。这里强调一点:修改shall之前必须区分它是普通文本还是代码注释里的内容。用正则做全量替换,会把注释里shall也被改掉,因此替换逻辑要复用第三章的代码块保护规则,只处理非代码区域。
5. 后续标准修订时,怎么让中英文D-PDU-API翻译不重做
ISO 22900-2已经发布多年,但集成到自家产品时仍会遇到补遗或修订。翻译工作最不想发生的事,是标准更新后已经完成的中文版全部作废。常用做法是把源语言按条款保存成片段仓库,每次只对变更片段重新执行DeePL翻译,并保留未变更片段的历史译文。
5.1 用git diff定位变化片段,再只翻译变化段落
将第一章提取的seg_*.txt全部纳入git仓库。标准新版本发布时,用git diff --stat看哪些片段文件的行数变化最大,再针对这些文件运行第三章的翻译脚本。由于DeePL有上下文窗口限制,每次只翻译变化的段落,其余段落直接复用上版中文翻译,可以显著节省API配额。
我的做法是把变化片段从seg_012.txt切出前20行作为上下文缓存,把真正的变化行放进单独的小文件,让DeePL参考缓存而不需要重复翻译全文。这个步骤虽然简单,但能避免DeePL因为缺少前文,把it指代理解成另一个对象。实际操作时,上下文缓存和真正变化行之间用一行-----隔开,翻译前把这一行换成“以下内容仅供参考”的英文提示,例如The following text is for context only,DeePL会把它当成上下文而不翻译。
5.2 三个快速检查保证双语文档可用
翻译完成后,不需要完整阅读整份PDF。先检查三件事:第一,所有__PDU_PH_占位符都已还原;第二,错误码表格里英文名与源语言一一对应;第三,输出文件里shall出现的次数与源文件里shall的次数差不超过百分之二。如果在连续多次更新后这三项都稳定,那就可以把翻译脚本部署成自动化任务,每次拿到修订版PDF后自动产出草案,再由工程师做针对性审校。
这套流程处理ISO 22900-2 D-PDU-API足够,同样也适用于ISO 22900-1、ISO 22901系列或者厂商内部基于此API扩展的私有规范。真正决定双语文档质量的是片段拆分、术语表和校验脚本,DeePL只是中间负责把自然语言转成中文的那一步。
本文还有配套的精品资源,点击获取