@compare-xml/core(JavaScript)
使用与网站相同的引擎解析并深度对比 XML 字符串。
@compare-xml/core 是一个用于深度对比 XML 文档的轻量 JavaScript/TypeScript 库,也是 Compare XML 使用的对比引擎。它通过 fast-xml-parser 解析 XML,并检测两个 XML 结构之间的新增、删除和值变更。
语言:JavaScript/TypeScript——通过 npm 分发。
安装
# npm
npm install @compare-xml/core
# yarn
yarn add @compare-xml/core
# pnpm
pnpm add @compare-xml/core
快速开始
import { compareXML } from '@compare-xml/core';
const baseXML = '<user><name>Alice</name><age>30</age><hobbies><item>reading</item></hobbies></user>';
const contrastXML = '<user><name>Bob</name><age>30</age><hobbies><item>reading</item><item>coding</item></hobbies><email>[email protected]</email></user>';
const differences = compareXML({ baseXML, contrastXML });
console.log(differences);
// [
// { pathSegments: ['user', 'name'], pathString: 'user.name', pathBelongsTo: 'both', diffType: 'valueChanged' },
// { pathSegments: ['user', 'hobbies', 'item'], pathString: 'user.hobbies.item', pathBelongsTo: 'both', diffType: 'valueChanged' },
// { pathSegments: ['user', 'email'], pathString: 'user.email', pathBelongsTo: 'contrast', diffType: 'added' },
// ]
默认的 byIndex 方法会把基准侧的单个 item 与对照侧的重复 item 集合作为该路径上的值进行对比。如果希望按索引对齐集合,请在两侧都使用重复元素。
对比选项
import { compareXML } from '@compare-xml/core';
// 元素和属性名大小写不敏感
compareXML({
baseXML: '<root><Name>Alice</Name></root>',
contrastXML: '<root><name>Alice</name></root>',
options: { keyCaseInsensitive: true },
});
// [](无差异)
// 文本和属性值大小写不敏感
compareXML({
baseXML: '<root><status>OK</status></root>',
contrastXML: '<root><status>ok</status></root>',
options: { valueCaseInsensitive: true },
});
// [](无差异)
解析器会自动将数字形式的元素文本和属性值转换为数字。XMLCompareOptions 中没有单独的数字字符串选项。
重复元素对比方法
重复的子元素(如多个 <item> 节点)会作为数组进行对比:
import { compareXML } from '@compare-xml/core';
// 'byIndex'(默认)——按相同索引逐一对比
compareXML({
baseXML: '<root><items><item>1</item><item>2</item><item>3</item></items></root>',
contrastXML: '<root><items><item>2</item><item>3</item><item>4</item></items></root>',
});
// 'lcs'——使用最长公共子序列对齐有序集合
compareXML({
baseXML: '<root><items><item>1</item><item>2</item><item>3</item></items></root>',
contrastXML: '<root><items><item>2</item><item>3</item><item>4</item></items></root>',
options: { arrayCompareMethod: 'lcs' },
});
// 'unordered'——将重复元素视为多重集
compareXML({
baseXML: '<root><items><item>1</item><item>2</item><item>3</item></items></root>',
contrastXML: '<root><items><item>3</item><item>2</item><item>1</item></items></root>',
options: { arrayCompareMethod: 'unordered' },
});
// [](无差异)
无序匹配会忽略位置,但不会忽略重复项的出现次数。相关示例和方法选择建议请参阅 XML 对比规则。
格式化路径
import { pathSegmentsToString } from '@compare-xml/core';
pathSegmentsToString(['users', '[0]', 'name']);
// 'users[0].name'
API 参考
compareXML
function compareXML(params: {
baseXML: string;
contrastXML: string;
options?: XMLCompareOptions;
}): XMLValueDifference[];
解析两个 XML 字符串并深度对比其结构。文档相等时返回空数组;任一输入不是格式良好的 XML 时抛出 XMLValidationError。
| 参数 | 类型 | 说明 |
|---|---|---|
baseXML | string | 基准 XML 字符串,视为原始一侧。 |
contrastXML | string | 与基准对比的 XML 字符串。 |
options | XMLCompareOptions | 可选的对比行为。 |
parseXML
function parseXML(xml: string): unknown;
使用 fast-xml-parser 将 XML 字符串解析为 JavaScript 值。属性名带 @ 前缀。
validateXML
function validateXML(xml: string): void;
校验字符串是否为格式良好的 XML。输入为空、仅包含空白或格式错误时抛出 XMLValidationError;有位置信息时,错误包含 line 和 col 属性。
pathSegmentsToString
function pathSegmentsToString(pathSegments: string[]): string;
将 XMLValueDifference.pathSegments 中的路径片段转换为可读字符串。数组索引片段不带前导点直接拼接,其他片段用 . 连接。
pathSegmentsToString([]); // ''
pathSegmentsToString(['user', 'name']); // 'user.name'
pathSegmentsToString(['items', '[2]', 'id']); // 'items[2].id'
XMLCompareOptions
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
arrayCompareMethod | XMLArrayCompareMethod | 'byIndex' | 重复元素的对比策略。 |
keyCaseInsensitive | boolean | false | 以大小写不敏感方式对比元素和属性名。 |
valueCaseInsensitive | boolean | false | 以大小写不敏感方式对比文本和属性值。 |
XMLArrayCompareMethod
type XMLArrayCompareMethod = 'byIndex' | 'lcs' | 'unordered';
| 值 | 说明 |
|---|---|
'byIndex' | 按相同索引逐一对比,多余的尾部元素报告为新增或删除。 |
'lcs' | 使用最长公共子序列对齐有序集合。 |
'unordered' | 将元素作为多重集进行匹配,忽略位置但统计重复次数。 |
XMLValueDiffType
type XMLValueDiffType = 'added' | 'deleted' | 'valueChanged';
| 值 | 说明 |
|---|---|
'added' | 元素或属性存在于 contrastXML 但不存在于 baseXML。 |
'deleted' | 元素或属性存在于 baseXML 但不存在于 contrastXML。 |
'valueChanged' | 基准与对照之间的值发生变化。 |
XMLValueDifference
| 字段 | 类型 | 说明 |
|---|---|---|
pathSegments | string[] | 路径片段,数组索引以 '[n]' 表示。 |
pathString | string | 点表示法路径,数组索引保留为方括号后缀。 |
pathBelongsTo | 'base' | 'contrast' | 'both' | 路径所属的一侧。 |
diffType | XMLValueDiffType | 在该路径检测到的差异类型。 |
XMLValidationError
class XMLValidationError extends Error {
line?: number;
col?: number;
}
当 XML 校验失败时由 validateXML 和 compareXML 抛出。解析器提供位置信息时,可读取 line 和 col。
许可证
MIT