ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

ISO 22900-2 D-PDU-API标准中英翻译:基于DeePL API的工程化实践

ISO 22900-2 D-PDU-API标准中英翻译:基于DeePL API的工程化实践 简介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标准先分片再交给DeePLISO 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_urlserver_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_urlhttps://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(), keylambda x: -len(x[0])): text text.replace(ph, original) return text for seg_file in sorted(glob.glob(seg_*.txt)): with open(seg_file, encodingutf-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_langZH-HANS, formalityprefer_less, # 技术文档少用“您”贴近操作描述 tag_handlingxml, ) translated restore(result.text) out_name seg_file.replace(.txt, .zh.md) with open(out_name, w, encodingutf-8) as f: f.write(translated)这段脚本最关键的是protect_code_block函数。它用正则匹配到连续两空格缩进的行先把整块代码存到列表再用__PDU_PH_000__一类占位符替换。DeePL会把这些占位符当作普通单词保留到译文里而不会给它们加入空格或改成中文。后面restore再把原始代码块回填。translate_text的两个参数值得单独说target_langZH-HANS指定简体中文如果你的读者使用繁体改成ZH-HANTformalityprefer_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 GlossaryDeePL官方的术语表功能可以直接在API请求里指定一个由源语言和译文对组成的XML或CSV词典。常见做法是新建一个CSV前两行分别写英文和中文之后每行放一对术语。对ISO 22900-2 D-PDU-API我的术语表里至少包含英文中文PDUPDUD-PDU APID-PDU APIprotocol layer协议层application layer应用层shall应may可以should宜error code错误码device设备module模块注意前三行里PDU和D-PDU API的译文故意保留英文。原因不难理解在代码上下文和工程口语里直接说“PDU”比说“协议数据单元”更不容易产生歧义。术语表建成后上传并获取一个glossary_idglossary translator.create_glossary( iso22900-2, source_langEN, target_langZH-HANS, entries{PDU: PDU, D-PDU API: D-PDU API, shall: 应} )后续翻译请求里加一个参数glossaryglossaryDeePL就会优先使用这些配对。和第三章的占位符保护相比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, encodingutf-8).read() tgt open(tgt_path, encodingutf-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 onlyDeePL会把它当成上下文而不翻译。5.2 三个快速检查保证双语文档可用翻译完成后不需要完整阅读整份PDF。先检查三件事第一所有__PDU_PH_占位符都已还原第二错误码表格里英文名与源语言一一对应第三输出文件里shall出现的次数与源文件里shall的次数差不超过百分之二。如果在连续多次更新后这三项都稳定那就可以把翻译脚本部署成自动化任务每次拿到修订版PDF后自动产出草案再由工程师做针对性审校。这套流程处理ISO 22900-2 D-PDU-API足够同样也适用于ISO 22900-1、ISO 22901系列或者厂商内部基于此API扩展的私有规范。真正决定双语文档质量的是片段拆分、术语表和校验脚本DeePL只是中间负责把自然语言转成中文的那一步。本文还有配套的精品资源点击获取
返回列表