比较 2 个 XSD 文件并将文件 2 中缺少的元素添加到文件 1

问题描述 投票:0回答:1

我的要求是比较具有嵌套结构的 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。

任何帮助将不胜感激。

javascript node.js xml xsd lodash
1个回答
0
投票

我能够自己找到解决方案。请找到上述问题的解决方案。

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;
}
© www.soinside.com 2019 - 2025. All rights reserved.