@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。

参数类型说明
baseXMLstring基准 XML 字符串,视为原始一侧。
contrastXMLstring与基准对比的 XML 字符串。
optionsXMLCompareOptions可选的对比行为。

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

选项类型默认值说明
arrayCompareMethodXMLArrayCompareMethod'byIndex'重复元素的对比策略。
keyCaseInsensitivebooleanfalse以大小写不敏感方式对比元素和属性名。
valueCaseInsensitivebooleanfalse以大小写不敏感方式对比文本和属性值。

XMLArrayCompareMethod

type XMLArrayCompareMethod = 'byIndex' | 'lcs' | 'unordered';
值说明
'byIndex'按相同索引逐一对比,多余的尾部元素报告为新增或删除。
'lcs'使用最长公共子序列对齐有序集合。
'unordered'将元素作为多重集进行匹配,忽略位置但统计重复次数。

XMLValueDiffType

type XMLValueDiffType = 'added' | 'deleted' | 'valueChanged';
值说明
'added'元素或属性存在于 contrastXML 但不存在于 baseXML。
'deleted'元素或属性存在于 baseXML 但不存在于 contrastXML。
'valueChanged'基准与对照之间的值发生变化。

XMLValueDifference

字段类型说明
pathSegmentsstring[]路径片段,数组索引以 '[n]' 表示。
pathStringstring点表示法路径,数组索引保留为方括号后缀。
pathBelongsTo'base' | 'contrast' | 'both'路径所属的一侧。
diffTypeXMLValueDiffType在该路径检测到的差异类型。

XMLValidationError

class XMLValidationError extends Error {
  line?: number;
  col?: number;
}

当 XML 校验失败时由 validateXML 和 compareXML 抛出。解析器提供位置信息时,可读取 line 和 col。

许可证

MIT