ARXML重复UUID如何解决?用Python脚本全局扫描替换保引用一致
“你们有没有人见过ARXML里 UUID 撞车的我当时调试一个通信矩阵合并的时候加载进去直接崩了日志里提示 duplicate identifier。后来查了半天根因就是两个软件组件定义里的 UUID 一模一样。更折腾的是这种文件有时一条 definition 里嵌套了十几个 UUID靠编辑器手动改根本不现实所以当时直接写了个 Python 脚本全局扫描、替换顺手把去重和映射关系也做了。”上面这段话不是讲故事是这类问题最常见的打开方式。AUTOSAR 的 ARXML 文件本质是 XML 描述格式用于描述 ECU 软件组件、接口、通信矩阵、数据映射等关键配置。XML 里大量使用 UUID 作为元素唯一标识工具链靠它做跨文件引用和模型关联。一旦 UUID 重复轻则工具报警重则导入失败、配置错乱、导致生成代码内容错配问题很隐蔽。这个需求的核心就是用 Python 脚本实现 ARXML 文件里 UUID 的全局扫描、去重、替换同时保证替换后引用的一致性。为什么要写脚本而不是手工改首选答案很简单量太大。一个项目里的 ARXML 文件动辄几十个单文件里 UUID 数量成百上千手动查找重复再逐条替换不仅耗时还极容易出人为错误。这里我会把这个脚本的设计思路、解析方式、关键代码、测试方法和排坑经验全部拆开讲清楚整个过程可复现。1. 项目整体设计与思路拆解1.1 需求本质不是“替换”而是“保证全局唯一性”表面上“修改重复的 UUID”只是做查找替换但实际做起来有三个层次找出重复的 UUID这是“诊断”把重复的 UUID 重新生成替换掉旧值这是“修正”最关键的是确保其他位置对旧 UUID 的引用也同步更新这是“一致性修复”。只做到前两步往往在工具加载时照样报错因为虽然 definition 里的 UUID 不重复了但其他元素还引用着已废弃的那个旧 UUID引用关系全部断掉模型完整性被破坏。这比 UUID 重复本身更麻烦。所以我一开始就把目标定为“全局唯一 引用一致性”而不是单纯去重。1.2 为什么选 Python 而不是直接手写 XML 工具ARXML 是 XML 的一种变体手工修改风险高。Python 的优势在于生态成熟有现成的 XML 解析库比如标准库 xml.etree.ElementTree和功能更完善的 lxml。单独处理 XML 序列化、命名空间、属性遍历这件事Python 是极稳妥的选择。另一个因素是团队协作脚本可以塞进 CI 流程也可以做成独立的修复工具某个环节做一次批量修复。有不少人问我用 sed 或者 perl 也能做全局替换为什么非要写 Python原因是它们做不了“语义级”解析。比如你直接在文本层替换 UUID无法区分哪个 UUID 是定义、哪个是引用也无法保留命名空间、处理属性顺序更没法输出重复前的变化映射。XML 属于结构化数据必须从结构层面处理才安全。1.3 方案选型对比ElementTree 与 lxml当前主流有两个处理方案对比项ElementTree标准库lxml依赖无需安装需要 pip 安装性能中等大文件偏慢快底层是 libxml2命名空间处理支持但不优雅支持更好序列化控制基本可用可控制缩进、属性排序适配场景中小数量 ARXML 文件大批量、大型文件更合适如果你的文件单文件超过 10MB或者总文件数超过 50 个我建议直接上 lxml。否则 ElementTree 也完全够用写出的脚本无额外依赖放到任何一台有 Python 的电脑上就能跑。我在实际项目中的选择是 lxml因为处理的是整个 ECU 项目里十几个大型 ARXML加载更快遍历属性也更灵活。1.4 整体流程设计整个脚本的流程拆成五个阶段扫描阶段遍历目标目录下所有 .arxml 文件解析 XML 树收集阶段找出所有带 UUID 属性的元素提取 UUID 值分析阶段统计重复项生成去重映射关系替换阶段对所有重复 UUID 生成新 UUID并在所有元素属性、文本引用中全局替换备份与输出替换前备份原文件输出变更映射日志。之所以强调先分析再替换是因为直接边遍历边替换会让重复判断失真——一个 UUID 可能在第一个文件里被替换成新值结果第二个文件里又匹配到旧值逻辑混乱。先完整收集、后统一替换可以保证判断的基准一致映射关系干净。2. 核心细节解析与实操要点2.1 ARXML 的 UUID 属性在哪里ARXML 的根元素常是AUTOSAR内部有大量子元素UUID 通常以 XML 属性的形式出现。常见形式如下AUTOSAR xsi:schemaLocation... AR-PACKAGES AR-PACKAGE uuid5b3f2e2c-... SHORT-NAMETestPackage/SHORT-NAME /AR-PACKAGE /AR-PACKAGES /AUTOSAR简单来说凡是模型元素定义基本上都会带一个uuid属性。不同工具生成的文件结构略有差异但uuid属性名基本一致完整扫描时只要遍历所有元素的attrib字典即可。2.2 命名空间处理是最大的隐藏坑ARXML 文件通常带命名空间比如AUTOSAR xmlnshttp://autosar.org/schema/r4.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance在 ElementTree 里直接访问element.attrib只能拿到未带命名空间前缀的属性。UUID 属性一般在默认命名空间下但如果你用find或iterfind查找元素必须带上完整的命名空间匹配否则查不到任何元素。这个坑我踩过一次脚本跑完提示“0 个 UUID 找到”半天定位到是命名空间的问题。为避免踩坑我的建议是不依赖元素的路径查找直接用iter()遍历所有元素遍历属性时直接遍历element.attrib.items()不硬编码命名空间前缀输出时保留根元素原有的命名空间声明不要重写。2.3 UUID 格式与生成策略标准的 UUID 是 32 位十六进制数通常写成 8-4-4-4-12 的分组格式例如5b3f2e2c-9f6a-4f1e-8b8a-5c9d2e4f7a01Python 生成新 UUID 直接使用标准库import uuid new_id str(uuid.uuid4())有一点值得提醒AUTOSAR 工具链对 UUID 格式的要求一般只要求是标准 UUID 格式且全局唯一并不要求特定版本。UUID4随机生成足够安全不需要特意用 UUID1基于时间和 MAC 地址因为后者在批量生成时反而可能出现时间戳碰撞。2.4 替换策略定义源节点与引用节点虽然从 XML 结构上看 UUID 都是属性但从模型语义上要区分“定义型 UUID”和“引用型 UUID”。定义型 UUID 是当前元素作为模型对象时声明的唯一标识引用型 UUID 则出现在某些引用属性中指向别的模型元素。理论上完美做法是保留引用关系只替换“定义型 UUID”再同步更新“引用型 UUID”。但实际操作中发现ARXML 里引用不一定用 UUID 属性承载更多时候用SHORT-NAME路径引用。因此更稳妥的通用方案是找出全部重复的 UUID对每个重复值生成一个新 UUID所有出现旧 UUID 的地方包括定义属性、引用属性、文本内容统一替换为新 UUID。这样做虽然会替换引用属性但因为新旧映射关系是 1 对 1 的只要映射关系不变模型的引用完整性就不会受影响。2.5 映射关系的记录方式每次替换必须保存修改记录建议输出一份 CSV 映射表字段包括old_uuid, new_uuid, file_path, element_path这个文件有两大用处如果替换后工具仍然报错可以通过映射表反查当初替换的位置如果后续不同团队之间需要同步变更映射表就是版本对照的依据。在实际项目里我把映射表也当成交付物之一在评审时直接作为变更说明附件省了不少沟通成本。3. 实操过程与核心代码实现3.0 环境准备我使用的是 Python 3.10安装了 lxml。如果你没有 lxml可以把 import 部分换成 ElementTree但后续序列化输出部分要做相应调整。个人经验是直接用 lxml 省心性能好API 也符合直觉。安装依赖pip install lxml3.1 扫描目录并收集 UUID首先写一个工具函数用于递归找到所有.arxml文件import os import uuid from lxml import etree def find_arxml_files(root_dir): arxml_files [] for root, dirs, files in os.walk(root_dir): for f in files: if f.lower().endswith(.arxml): arxml_files.append(os.path.join(root, f)) return arxml_files然后定义收集 UUID 的函数def collect_all_uuids(arxml_files): uuid_locations {} for file_path in arxml_files: tree etree.parse(file_path) root tree.getroot() for elem in root.iter(): for attr_name, attr_value in elem.attrib.items(): if attr_value and is_valid_uuid(attr_value): uuid_locations.setdefault(attr_value, []).append( (file_path, elem.tag, attr_name) ) return uuid_locationsis_valid_uuid用正则校验格式即可import re UUID_PATTERN re.compile( r^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ ) def is_valid_uuid(value): return bool(UUID_PATTERN.match(value))这一步把路径和元素都记录下来方便后续输出映射表时定位精确位置。3.2 分析重复项并生成新 UUID拿到全量 UUID 记录后第二步就是判断重复def find_duplicates(uuid_locations): dup_uuids {} for uuid_val, locations in uuid_locations.items(): if len(locations) 1: dup_uuids[uuid_val] locations return dup_uuids注意这里判断重复的标准是“出现在多个位置”不是“出现在多个文件”。同一个 UUID 如果在同一个文件里出现两次同样会被识别为重复。这种设计是为了严格保证全局唯一性宁可把同一文件内的 UUID 冲突也一并修复。生成新 UUID 并构建映射def build_uuid_mapping(dup_uuids): mapping {} for old_uuid, locations in dup_uuids.items(): # 保留第一个位置作为“原始定义”其余替换 # 但统一策略更简单所有位置都替换为新 UUID保持一致性 new_uuid str(uuid.uuid4()) mapping[old_uuid] new_uuid return mapping这里的“保留第一个位置”策略我看有一些人这么处理。但从工具链角度说如果同一个 UUID 本身就是重复的那么保留任何一个“原定义”都没有实质区别——重复意味着模型本身就有歧义。最稳妥的做法是所有出现位置统一替换成同一个新 UUID把这条定义彻底“改名重发”。3.3 全局替换过程替换过程是最核心的环节。这里要注意不能只替换uuid属性还必须检查所有属性值和元素的文本内容防止某些工具把 UUID 写成文本def replace_uuids_in_file(file_path, uuid_mapping): tree etree.parse(file_path) root tree.getroot() replaced_records [] for elem in root.iter(): # 检查属性 for attr_name, attr_value in list(elem.attrib.items()): if attr_value in uuid_mapping: old_attr attr_value elem.set(attr_name, uuid_mapping[attr_value]) replaced_records.append( (file_path, elem.tag, attr_name, old_attr, uuid_mapping[attr_value]) ) # 检查文本内容极少见但做了更稳妥 if elem.text and elem.text.strip() in uuid_mapping: old_text elem.text.strip() elem.text uuid_mapping[elem.text.strip()] replaced_records.append( (file_path, elem.tag, __text__, old_text, uuid_mapping[elem.text.strip()]) ) tree.write(file_path, encodingUTF-8, xml_declarationTrue, pretty_printTrue) return replaced_records这里有个细节在用 lxml 回写文件时pretty_printTrue会重新格式化 XML缩进和原文件可能不一致。如果你们对源码格式有强要求这个行为需要提前告知团队或者直接用xml_declarationTrue而不加pretty_print。实际项目里格式化差异影响不大因为 ARXML 本来就是工具链生成的可读性基本不依赖原始缩进。3.4 完整主流程示例把上面的函数串起来主流程如下def main(root_dir, output_dirNone): arxml_files find_arxml_files(root_dir) uuid_locations collect_all_uuids(arxml_files) dup_uuids find_duplicates(uuid_locations) if not dup_uuids: print(未发现重复 UUID脚本结束。) return uuid_mapping build_uuid_mapping(dup_uuids) all_records [] for file_path in arxml_files: # 先做备份 if output_dir: backup_path os.path.join( output_dir, backup_ os.path.basename(file_path) ) shutil.copy2(file_path, backup_path) replaced_records replace_uuids_in_file(file_path, uuid_mapping) all_records.extend(replaced_records) # 输出映射表 with open(os.path.join(output_dir or root_dir, uuid_mapping.csv), w, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerow([old_uuid, new_uuid, file_path, elem_tag, attr_name, old_value, new_value]) for old, new in uuid_mapping.items(): writer.writerow([old, new, , , , , ]) for rec in all_records: writer.writerow([rec[3], rec[4], rec[0], rec[1], rec[2], rec[3], rec[4]]) print(f替换完成共发现重复 UUID {len(dup_uuids)} 个涉及 {len(all_records)} 处修改。)主流程有几个设计点说明一下备份策略默认备份到独立目录不污染源目录不加备份的话一旦脚本有 bug原文件直接写完没法回滚。我做任何批量改文件的脚本第一步永远是备份CSV 输出单独一份 mapping 文件既方便追溯也方便 CI 留档返回结构每个替换记录都带有路径和位置用于后续审计。3.5 关于性能和数据量级的经验一个大型 ECU 项目里ARXML 文件总数大概在 20~30 个每个文件大小在 5MB~30MB 之间元素节点上万甚至几十万。用 lxml 遍历一遍整个过程不过几秒到十几秒。如果文件数量更大可以按以下思路优化多进程按文件并行遍历先做一次快速正则扫描过滤掉根本不包含uuid字符串的文件再进入 XML 解析阶段避免重复 parse 同一个文件。实际上即使在最坏情况下整个过程也就是分钟级很难成为瓶颈。真正的瓶颈往往在后期的工具链验证上。4. 常见问题与排查技巧实录4.1 问题脚本运行正常但工具还报 UUID 重复这种情况最多见原因通常是工具把某些 UUID 存在了.arxml之外的其他文件中你只改了当前目录里的 ARXMLUUID 出现在二进制编码或者注释里XML 解析器默认不会处理注释节点工具内部有缓存之前加载过的旧配置还占着内存。排查建议先回看工具有没有--refresh或者清缓存选项或者把所有相关文件打包搜索一次确认 UUID 唯一性。4.2 问题提示找不到任何 UUID大概率是命名空间问题或遍历逻辑问题。用 lxml 时注意elem.attrib中键可能带{namespace}attr前缀不要直接比较字符串。建议先打印前几个元素的 attrib 字典确认属性 key 的实际表现。4.3 问题替换后文件打不开或结构损坏这多半是 XML 解析时本身已存在非法字符或未转义内容。lxml 默认对格式错误的 XML 直接抛异常此时需要先修复原文件。如果确认原文件是合法的那问题极可能出在写回时没有保留xml_declaration导致编码声明丢失工具按默认编码解析失败。回写时要保留tree.write(file_path, encodingUTF-8, xml_declarationTrue)4.4 常见问题速查表问题可能原因排查/修复方法脚本没有替换任何 UUID命名空间问题或属性名不是 uuid打印 elem.attrib 检查实际属性键名工具仍提示 UUID 重复有其他文件未纳入扫描或工具缓存扩大扫描范围清工具缓存重载替换后文件编码乱码写回文件丢失 encoding/xml_declaration写文件时带上 encoding 和 xml_declaration替换后缩进格式异常pretty_print 重新格式化不加 pretty_print 或提前告知团队原文件只读导致写失败文件权限或只读属性脚本中显式处理权限或提前 chmod发现有重复但脚本没识别值大小写不一致比较前统一转小写再做匹配4.5 推荐预案先 DDL 模拟再动真库我的习惯是先在模拟项目上跑一遍脚本验证输出的文件能被工具正常打开再跑真实项目。所谓模拟项目就是复制 2~3 个 ARXML 文件手改几个 UUID 制造重复用它做基准测试。这样做有两个好处一是快速验证脚本逻辑二是能确认你的工具链对“新 UUID”没有任何格式洁癖。5. 项目扩展方向写完这个脚本后我后来在多个项目里复用了这套思路只是做了点扩展支持扫描参数文件中的 UUID不止 ARXML还能扫 .xml 和 .json支持命令行参数传入目录、输出目录、dry-run 模式只输出映射表不改文件支持把映射结果直接生成一份 markdown 报告方便评审展示。这套代码的架构本身不绑定 ARXML 这个特定格式任何“XML 中全局替换属性值”的需求都能套用只要调整文件扩展名和属性名即可。我个人在实际操作中的体会是写脚本本身并不复杂复杂的是想清楚“替换后数据仍然是一致的”这件事。如果你只是机械地换掉字符串而不理解元素间的引用关系替换完反而毁掉整个模型。所以每次写这类脚本前我都会花时间先回答一个问题哪些地方在“定义”这个 UUID哪些地方在“引用”这个 UUID替换的原则是什么。搞清楚这一点代码怎么写都是顺的。最后再分享一个小技巧如果团队里有多个工具链在混用替换 UUID 后最好做一次全量导出导入验证确认没有工具在内部偷偷缓存了旧值。你会发现真正能验证脚本写得好不好的从来不是代码本身而是整套工具链能不能顺利跑通。

相关新闻

840Dsl调试必备:STEP7 ToolBox安装与项目组态避坑指南

840Dsl调试必备:STEP7 ToolBox安装与项目组态避坑指南

简介:面向西门子SINUMERIK 840D sl数控系统的电气调试与维修人员,这是一份STEP7环境下的ToolBox 4.8.07调试工具箱,常用于系统上电后的PLC组态、轴驱动配置、机床参数备份与恢复等实际工作场景。压缩包采用zip格式封装,整体大小约…

2026/10/15 23:30:47 阅读更多 →
C语言链接原理与实战:从undefined reference到可执行文件

C语言链接原理与实战:从undefined reference到可执行文件

1. 这不是“编译完就结束”的事:链接阶段才是程序真正成形的关键一环很多人写完C代码,敲下gcc main.c -o main看到可执行文件生成,就以为大功告成。但其实,从源码到能双击运行的二进制文件,中间隔着一个被严重低估、却…

2026/10/15 23:30:47 阅读更多 →
Elasticsearch核心原理与生产实践:从索引、分片到集群排障

Elasticsearch核心原理与生产实践:从索引、分片到集群排障

搜索引擎能做到的事情,远不是数据库里那些LIKE %关键词%能替代的。ElasticSearch 是我这些年接触过的技术栈里,最“用得越深、敬畏心越强”的一个中间件。早期我以为它就是个“能搜的快一点的东西”,直到做完几个企业级项目,踩过集…

2026/10/15 23:29:46 阅读更多 →

最新新闻

Everything秒搜百万文件,NTFS索引原理与高效文件搜索实战

Everything秒搜百万文件,NTFS索引原理与高效文件搜索实战

有一次我在项目收尾阶段找一份两年前的报价单,Windows 自带的搜索转了半天,出来半屏无关的碎片文件,气得我差点重装系统。后来同事随口说了句“你可以试试 Everything,百万文件几秒就能索引完”,我心里是不信的——系统…

2026/10/17 9:09:31 阅读更多 →
迪文串口TFT屏通用驱动:DGUS1/DGUS2双协议自动识别与HMI工程化封装

迪文串口TFT屏通用驱动:DGUS1/DGUS2双协议自动识别与HMI工程化封装

简介:本资源是一套专为AVR单片机平台开发的迪文串口TFT屏通用驱动程序,面向嵌入式初学者与工业人机界面开发者,解决在AVR系统中快速集成迪文DWIN系列串口屏的底层通信与图形显示难题。驱动采用标准C语言编写,具备高可读性与跨型号…

2026/10/17 9:09:31 阅读更多 →
superpowers实战:让Claude Code/Codex CLI按工程流程写代码

superpowers实战:让Claude Code/Codex CLI按工程流程写代码

如果你最近搜过“superpowers 使用教程”“codex superpowers”这组关键词,八成已经跟我一样,开始把 Claude Code 或 Codex CLI 当成日常写代码的搭档了。我最初接触 superpowers,就是因为被 AI 助手“写一半就跑偏”的尴尬折磨到不行&#x…

2026/10/17 9:09:31 阅读更多 →
superpowers:为Codex CLI装上可扩展技能包,让AI编码从自由发挥到规范工作流

superpowers:为Codex CLI装上可扩展技能包,让AI编码从自由发挥到规范工作流

如果你手头有一个AI编码助手,比如Codex CLI,你一定遇到过这样的场景:让它改个bug,它能改,但改完又引入新问题;让它写个功能,它能写,但面对几十个文件的项目,它经常顾头不…

2026/10/17 9:09:31 阅读更多 →
PyTorch多类别语义分割实战:从彩色标注到Unet推理全链路

PyTorch多类别语义分割实战:从彩色标注到Unet推理全链路

简介:这份资源面向具备一定深度学习基础的开发者与图像分析方向的学习者,提供在PyTorch框架下实现Unet多类别语义分割的完整代码工程,可用于医学影像、遥感图像等场景的像素级分类任务。压缩包共46个文件,约69KB,以19个…

2026/10/17 9:09:31 阅读更多 →
UL 1973-2022储能电池安全标准实操指南

UL 1973-2022储能电池安全标准实操指南

简介:本资源为UL 1973:2022《固定和机动辅助动力应用电池安全标准》第三版中文翻译版PDF,是北美储能行业核心准入依据,面向电池系统工程师、储能产品认证人员、安规测试实验室技术人员及出海企业研发团队,用于指导电芯与系统级安全…

2026/10/17 9:08:30 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →