
模组工具。X4:奠基的XML差异与修补工具
该工具是用于《X4: 基石》的简易XML差异对比与补丁工具。旨在帮助模组制作者对比和修补XML文件。差异XML文件的格式与gave diff.xsd格式定义兼容。这意味着——你可以
查看大图模组制作工具:X4:基奠的XML差异与补丁工具
本工具集是为X4:基奠设计的简易XML差异与补丁工具。旨在帮助模组制作者比较和修补XML文件。
差异XML文件的格式与相应的 diff.xsd 格式定义兼容。这意味着,你可以使用此工具为游戏中使用的任何XML文件创建差异文件。 同样,你可以使用相应的工具来用差异文件修补XML文件,这样做有助于检查你的差异文件将如何应用到原始XML文件,或者更好地理解其他模组制作者在他们的模组中所做的修改。
重要说明
强烈建议使用 diff.xsd 文件来验证差异XML文件。在使用 XMLDiff.exe 创建它们时尤其重要。
但当前版本的 diff.xsd 文件(随游戏版本 8.00HF3/4 分发)有一个 显著的限制——它对 replace 操作规则非常严格。它只支持 replace 元素中包含一个子元素。这意味着,如果你的文件中 replace 元素包含多个子元素,验证将会失败。因此,在这种情况下请不要使用 diff.xsd 文件进行验证。
如果 diff.xsd 文件位于“当前”文件夹中,它将被自动使用。如果你想使用另一个 diff.xsd 文件,可以使用 -x 选项指定。
如何使用
- 从以下位置下载最新版本:
- 将存档文件解压到任意目标位置。
- 内部将有一个名为 XMLDiffAndPatch 的文件夹,包含两个可执行文件——XMLDiff.exe 和 XMLPatch.exe。
如何创建差异文件
以下是 XMLDiff 工具的命令行帮助:
XMLDiff 1.0.1
Developed by Chem O`Dun
-o, --original_xml Required. Original XML file or directory.
-m, --modified_xml Required. Modified XML file or directory.
-d, --diff_xml Required. Output diff file or directory.
-x, --xsd Path to diff.xsd (default: diff.xsd).
-l, --log-to-file Enable file logging at the specified level: error|warn|info|debug. Console always logs at info level.
-a, --append-to-log (Default: false) Append to existing log file instead of overwriting.
--only-full-path (Default: false) Generate only full absolute XPath (no // shorthand).
--use-all-attributes (Default: false) Include all attributes in XPath predicates.
--ignore-diff-in-attribute Attribute name to ignore when comparing elements.
--help Display this help screen.
--version Display version information.
示例:
XMLDiff.exe -o vanilla.xml -m modified.xml -d diff.xml
生成的差异文件示例
以下是工具创建的差异文件示例:
- 带有 add 操作:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<diff>
<add sel="//ware[@id="scanningarrays"]" pos="before">
<ware id="xenon_psi_emitter_mk1" name="{1972092403, 7002}" description="{1972092403, 7002}" transport="equipment" volume="1" tags="satellite noplayerbuild">
<price min="845800" average="901420" max="1054580" />
<production time="60" amount="0" method="default" name="Xenon Psi Emitter" />
<production time="60" amount="0" method="xenon" name="Xenon Psi Emitter" />
<production time="60" amount="0" method="terran" name="Xenon Psi Emitter" />
<component ref="xenon_psi_emitter_macro" amount="0" />
<use threshold="0" />
</ware>
</add>
</diff>
- 带有 replace 操作:
<?xml version='1.0' encoding='UTF-8'?>
<diff>
<replace sel="//do_if[@value="@$speak and not this.assignedcontrolled.nextorder and (@$defaultorder.id != 'Patrol') and (@$defaultorder.id != 'ProtectPosition') and (@$defaultorder.id != 'ProtectShip') and (@$defaultorder.id != 'ProtectStation') and (@$defaultorder.id != 'Plunder') and (@$defaultorder.id != 'Police') and (not this.assignedcontrolled.commander or (this.assignedcontrolled.commander == player.occupiedship)) and notification.npc_await_orders.active"]/@value">@$speak and not this.assignedcontrolled.nextorder and (@$defaultorder.id != 'ProtectSector') and (@$defaultorder.id != 'Patrol') and (@$defaultorder.id != 'ProtectPosition') and (@$defaultorder.id != 'ProtectShip') and (@$defaultorder.id != 'ProtectStation') and (@$defaultorder.id != 'Plunder') and (@$defaultorder.id != 'Police') and (not this.assignedcontrolled.commander or (this.assignedcontrolled.commander == player.occupiedship)) and notification.npc_await_orders.active</replace>
</diff>
路径选项
默认:全局唯一时使用 // 简写
默认情况下,当元素在文档中全局唯一时,工具会使用 // XPath 简写,生成更短、更具可读性的 sel 路径。
示例:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<diff>
<add sel="//ware[@id="scanningarrays"]" pos="before">
<ware id="xenon_psi_emitter_mk1" ...>
...
</ware>
</add>
</diff>
--only-full-path:始终使用完整绝对路径
--only-full-path 选项强制工具始终生成完整路径(以 /rootElement/... 开头),并且从不使用 // 简写。
示例:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<diff>
<add sel="/wares/ware[@id="scanningarrays"]" pos="before">
<ware id="xenon_psi_emitter_mk1" name="{1972092403, 7002}" description="{1972092403, 7002}" transport="equipment" volume="1" tags="satellite noplayerbuild">
<price min="845800" average="901420" max="1054580" />
<production time="60" amount="0" method="default" name="Xenon Psi Emitter" />
<production time="60" amount="0" method="xenon" name="Xenon Psi Emitter" />
<production time="60" amount="0" method="terran" name="Xenon Psi Emitter" />
<component ref="xenon_psi_emitter_macro" amount="0" />
<use threshold="0" />
</ware>
</add>
</diff>
最小化XPath属性谓词
工具仅在需要使路径步骤在其父元素内唯一时,才会添加属性谓词。如果元素名称在那一级已经唯一,则不添加任何属性。只有直到实现唯一性时,才逐一追加额外的属性。
与总是包含第一个属性(无论是否需要)相比,这会产生更简洁、更具可读性的 sel 路径。
在XPath中使用所有属性
--use-all-attributes 选项强制将元素的所有属性包含在其 XPath 谓词中,无论其唯一性如何。当需要最大特异性时很有用。
示例:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<diff>
<add sel="/wares/ware[@id="scanningarrays"][@name="{20201,3301}"][@description="{20201,3302}"][@factoryname="{20201,3304}"][@group="hightech"][@transport="container"][@volume="38"][@tags="container economy"]" pos="before">
<ware id="xenon_psi_emitter_mk1" name="{1972092403, 7002}" description="{1972092403, 7002}" transport="equipment" volume="1" tags="satellite noplayerbuild">
<price min="845800" average="901420" max="1054580" />
<production time="60" amount="0" method="default" name="Xenon Psi Emitter" />
<production time="60" amount="0" method="xenon" name="Xenon Psi Emitter" />
<production time="60" amount="0" method="terran" name="Xenon Psi Emitter" />
<component ref="xenon_psi_emitter_macro" amount="0" />
<use threshold="0" />
</ware>
</add>
</diff>
忽略指定属性的差异
--ignore-diff-in-attribute 选项会在比较元素时忽略指定属性的差异。当你想要忽略诸如 version、comment 等属性的差异时很有用。
通过内联注释定义差异的位置生成
add 的 pos 属性通常设置为 after,考虑到程序运行的通用逻辑。但在某些情况下,你可能希望差异文件的 pos 属性设置为 before。这在配合 VS Code 使用时特别有用。 你可以通过在原始XML文件中使用内联注释来定义差异文件中 add 元素的位置。注释应放置在要添加的元素之前,并包含文本 。
如何应用差异文件
以下是 XMLPatch 工具的命令行帮助:
XMLPatch 1.0.1
Developed by Chem O`Dun
-o, --original_xml Required. Path to the original XML file or directory.
-d, --diff_xml Required. Path to the diff XML file or directory.
-u, --output_xml Required. Path for the output XML file or directory.
-x, --xsd Path to diff.xsd (default: diff.xsd).
-l, --log-to-file Enable file logging at the specified level: error|warn|info|debug. Console always logs at info level.
-a, --append-to-log (Default: false) Append to existing log file instead of overwriting.
--allow-doubles (Default: false) Skip duplicate-element guard when applying <add> operations.
--help Display this help screen.
--version Display version information.
示例:
XMLPatch.exe -o vanilla.xml -d diff.xml -u modified.xml
生成的修补XML文件示例
以下是工具创建的修补XML文件示例:
- 带有 add 操作:
<ware id="satellite_mk2" name="{20201,20401}" description="{20201,20402}" transport="equipment" volume="1" tags="equipment satellite">
<price min="44380" average="52215" max="60045"/>
<production time="60" amount="1" method="default" name="{20206,101}">
<primary>
<ware ware="advancedelectronics" amount="5"/>
<ware ware="energycells" amount="10"/>
<ware ware="scanningarrays" amount="5"/>
</primary>
</production>
<production time="60" amount="1" method="xenon" name="{20206,601}" tags="noplayerbuild">
<primary>
<ware ware="energycells" amount="10"/>
<ware ware="silicon" amount="1"/>
</primary>
</production>
<component ref="eq_arg_satellite_02_macro"/>
<use threshold="0"/>
</ware>
<ware id="xenon_psi_emitter_mk1" name="{1972092403, 7002}" description="{1972092403, 7002}" transport="equipment" volume="1" tags="satellite noplayerbuild">
<price min="845800" average="901420" max="1054580"/>
<production time="60" amount="0" method="default" name="Xenon Psi Emitter"/>
<production time="60" amount="0" method="xenon" name="Xenon Psi Emitter"/>
<production time="60" amount="0" method="terran" name="Xenon Psi Emitter"/>
<component ref="xenon_psi_emitter_macro" amount="0"/>
<use threshold="0"/>
</ware>
- 带有 replace 操作:
<set_to_default_flight_control_model object="this.assignedcontrolled"/>
<set_value name="$defaultorder" exact="this.assignedcontrolled.defaultorder"/>
<do_if value="@$speak and not this.assignedcontrolled.nextorder and (@$defaultorder.id != 'Patrol') and (@$defaultorder.id != 'ProtectSector') and (@$defaultorder.id != 'ProtectPosition') and (@$defaultorder.id != 'ProtectShip') and (@$defaultorder.id != 'ProtectStation') and (@$defaultorder.id != 'Plunder') and (@$defaultorder.id != 'Police') and (not this.assignedcontrolled.commander or (this.assignedcontrolled.commander == player.occupiedship)) and notification.npc_await_orders.active">
<set_value name="$speakline" exact="10304" comment="Awaiting orders."/>
如果输出XML是目录
如果输出XML是目录,工具将在输出目录中创建一个与原始XML文件名相同的新XML文件。 例如,如果原始XML文件是 vanilla.xml,输出目录是 output,工具将创建一个新XML文件 output/vanilla.xml。
如何将工具应用于目录
将XMLDiff应用于目录
您可以将XMLDiff工具应用于目录。在这种情况下,工具将遍历目录结构并为具有相同名称和相对路径的XML文件创建差异文件。过程如下:
- 如果所有输入参数都是目录,工具将为目录中的所有XML文件创建差异文件。
- 工具将递归遍历目录结构,使用修改后的文件作为“键”。
- 对于每个更改的文件,将检查原始目录中具有相同相对路径的相应原始XML文件。
- 如果找不到原始XML文件,则跳过该操作。
- 如果找到原始XML文件,则在输出目录中创建具有相同相对路径的差异文件。
示例:
XMLDiff.exe -o vanilla_dir -m modified_dir -d diff_dir
将XMLPatch应用于目录
您可以将XMLPatch工具应用于目录。在这种情况下,工具将遍历目录结构并将补丁应用于具有相同名称和相对路径的XML文件。过程如下:
- 如果所有输入参数都是目录,工具将为目录中的所有XML文件应用补丁。
- 工具将递归遍历目录结构,使用差异文件作为“键”。
- 对于每个差异文件,将检查原始目录中具有相同相对路径的相应原始XML文件。
- 如果找不到原始XML文件,则跳过该操作。
- 如果找到原始XML文件,则将差异文件与原始XML文件修补,并在输出目录中创建一个新的修补XML文件,具有相同的相对路径。
示例:
XMLPatch.exe -o vanilla_dir -d diff_dir -u modified_dir
问题报告
如果您使用工具有任何问题,请在问题页面上创建一个问题。 如果您能提供所用工具的版本以及相应的 XMLDiff.log 或 XMLPatch.log 文件,我们将不胜感激。 要创建这样的日志文件,请使用 -l 选项并指定 debug 级别,例如 -l debug。控制台输出始终是 info 级别;详细的调试信息仅写入文件。
许可证
本工具根据 Apache License, Version 2.0 许可证授权。您可以在 LICENSE 文件中找到它。
鸣谢
特别感谢 Duncaroos 的耐心、测试和宝贵的反馈。
附加链接
EGOSOFT论坛 上有一个与本工具集相关的主题。
防病毒扫描
请注意——每个发布存档都有指向 VirusTotal 的相应链接。请点击链接以确保存档安全。
更新日志
[1.0.3] - 2026-05-15
- 修复:
- 单个属性更改处理。
- 文本节点比较。
[1.0.2] - 2026-05-15
- 改进:
- 日志记录。
[1.0.1] - 2026-05-15
- 改进:
- 完全内部重写。
[0.2.31] - 2026-05-15
- 修复:
- XMLDiff:replace/remove 操作的属性检测逻辑
[0.2.30] - 2026-05-15
- 修复:
- XMLDiff:replace/remove 操作检测逻辑
[0.2.29] - 2026-03-02
- 改进:
- XMLDiff:replace 操作检测逻辑
[0.2.28] - 2026-02-22
- 改进:
- XMLDiff 和 XMLPatch:增加了处理多行 replace 差异元素的可能性。
[0.2.27] - 2025-08-28
- 改进:
- XMLDiff:添加了 --ignore-diff-in-attribute 选项,用于在比较元素时忽略指定属性的差异。当您想忽略 X4 脚本文件中 version 属性的差异时很有用。
[0.2.26] - 2025-06-16
- 改进:
- XMLDiff:增加了对修改后的XML文件中 add 元素的内联注释处理。允许在差异文件中定义 add 元素的 position 属性。
[0.2.25] - 2025-03-31
- 修复:
- XMLDiff:修复了遗漏根元素属性比较的问题
- XMLDiff:修复了在后续差异操作中使用已删除元素路径的问题
- XMLDiff:修复了在 XPath 中寻址元素时索引号不正确的问题
- XMLDiff:修复了通过 XPath 中的 sibling 关键字识别元素的问题
[0.2.24] - 2025-03-17
- 改进:
- 两个工具:结果文件夹将在递归处理中创建,现在与单个文件的方式相同。
- XMLDiff:在 XPath 中对元素使用 sibling 关键字。
- XMLDiff:当元素有可以唯一标识它的子元素时,生成 XPath。
- 更改:
- XMLDiff:--only-full-path 选项替换为 --anywhere-is-allowed。并且默认行为是使用完整路径。
- 两个工具:控制台的日志级别不会比日志文件更详细。
- 两个工具:未知选项将被忽略。
- 修复:
- XMLDiff:如果使用了多个属性,XPath 中元素的第一个属性重复出现。
[0.2.23] - 2025-03-15
- 修复:
- XMLDiff:修复了最后一个子元素比较的问题(索引越界)
[0.2.22] - 2025-03-10
- 改进:
- XMLDiff:元素的第一个属性将始终被添加到 XPath 中,以使差异更清晰。
- XMLDiff:如果一个属性不足以定义该元素,则将下一个属性添加到 XPath,迭代进行。
- XMLDiff:添加了关于通过 RunXMLDiff.bat 脚本和相应扩展与 VSCode 集成的简短描述,以便在编辑 XML 文件(修改过的)时“即时”创建差异。
[0.2.21] - 2025-03-03
- 修复:
- XMLDiff:修复了文本节点不同的问题
- XMLDiff:改进了“pos”定义逻辑
- XMLDiff:改进了日志信息
- 新增:
- XMLPatch:添加了 --allow-doubles 选项,对脚本修补很有用
- XMLPatch:添加了注释处理,现在注释将被添加到结果 XML 文件中
[0.2.20] - 2025-02-27
- 修复:
- XMLDiff:路径的错误属性选择
- XMLDiff:修复了未应用 --append-to-log 选项的问题
- XMLDiff:修复了更改属性计数检测错误的问题
- XMLDiff:修复了对元素使用 remove/add 而不是 replace 的问题
- XMLPatch:跳过没有 diff 元素的差异文件
- 改进:
- 两个工具:--log-to-file 选项现在需要日志级别(error、warn、info、debug)作为参数
[0.2.17] - 2025-02-25
- 修复:
- 添加了检查以防止在添加过程中出现重复元素
[0.2.16] - 2025-02-25
- 修复:
- 修复了元素替换的问题
- 改进:
- 日志信息
[0.2.15] - 2025-02-24
- 修复:
- 修复了加载 diff.xsd 的问题
- 修复了结果文件必须位于当前文件夹时的问题
- 改进: 日志信息,特别是关于错误的 sel 值。记录了更多关于已处理的 XML 元素的信息。
- 新增:
- 支持附加到已有的调试日志
[0.2.14] - 2025-01-17
- 新增:
- 第一个用 C# 编码的公开版本。
正在加载版本记录…
正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。