我的要求是比较具有嵌套结构的 2 个 XSD 文件(file1.xsd 和 file2.xsd)。我需要将 file2 中缺少的元素添加到 file1(假设 file1 是基础,其他元素需要从 file2 添加到基础,即 file1.
我正在考虑将 xsd 转换为 json,然后使用 lodash 中的一些 mergeWith 函数进行组合,然后再转换回 xsd。这个想法似乎可行吗?
提供示例输入文件和所需的输出。
文件1.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="child1" type="xs:string"/>
<xs:element name="child2">
<xs:complexType>
<xs:sequence>
<xs:element name="grandchild1" type="xs:string"/>
<xs:element name="grandchild2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
file2.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="child1" type="xs:string"/>
<xs:element name="child2">
<xs:complexType>
<xs:sequence>
<xs:element name="grandchild1" type="xs:string"/>
<xs:element name="grandchild3" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
需要输出.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="child1" type="xs:string"/>
<xs:element name="child2">
<xs:complexType>
<xs:sequence>
<xs:element name="grandchild1" type="xs:string"/>
<xs:element name="grandchild2" type="xs:string"/>
<xs:element name="grandchild3" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
可以看到,file1.xsd(base)中缺少的grandchild3经过比较后从file2添加到file1。
任何帮助将不胜感激。
我能够自己找到解决方案。请找到上述问题的解决方案。
const fs = require('fs');
const xml2js = require('xml2js');
const path = require('path');
const pre = 'xs';
let schema = `${pre}:schema`;
let element = `${pre}:element`;
let complexType = `${pre}:complexType`;
let sequence = `${pre}:sequence`;
// Read the XSD files
const file1 = fs.readFileSync('file1.xsd');
const file2 = fs.readFileSync('file2.xsd');
// Parse the XSD files using xml2js
const parser = new xml2js.Parser();
let xsd1, xsd2;
parser.parseString(file1, (err, result) => {
if (err) throw err;
xsd1 = result;
});
parser.parseString(file2, (err, result) => {
if (err) throw err;
xsd2 = result;
});
findMissingElements(xsd1[schema], xsd2[schema]);
const builder = new xml2js.Builder();
const updatedXsd = builder.buildObject(xsd1);
fs.writeFileSync('file-updated.xsd', updatedXsd);
function findMissingElements(schema1, schema2) {
const elementsToAdd = [];
// Check all top-level elements in schema2
for (const element2 of schema2[element] || []) {
const element1 = schema1[element]?.find((e) => e.$.name === element2.$.name);
if (!element1) {
elementsToAdd.push(element2);
} else {
// Check nested elements and types
const cType = element2[complexType];
if (cType) {
if (element2[complexType][0]?.[sequence]?.[0]) {
delete element1['$']['type']; // to remove type attribute (if any) from elements which are complex types
element1[complexType] = element1[complexType] || [{}];
element1[complexType][0][sequence] = element1[complexType][0][sequence] || [{}];
element1[complexType][0][sequence][0][element] = element1[complexType][0][sequence][0][element] || [];
element1[complexType][0][sequence][0][element].push(...findMissingElements(element1[complexType][0][sequence][0], element2[complexType][0][sequence][0]));
}
}
}
}
return elementsToAdd;
}