Как преобразовать xml структуру-исходник по xml структуре-образец?

Есть две xml структуры: исходник(И) и образец(О).
Требуется:
1. Из (И) удалить узлы, которые отсутствует в (О).
2. Из (О) добавить узлы, которые отсутствуют в (И). Добавляемые узлы заполнить значениями из (О).

Пример

Исходник
<CatalogObject.Организации>
	<Поле1>исходник. поле1</Поле1>
	<Поле2>исходник. поле2</Поле2>
	<Поле3/>
	<Таблица1>
		<Строка>
			<Колонка1>исходник. таблица 1. строка1. колонка1</Колонка1>
			<Колонка2>исходник. таблица 1. строка1. колонка2</Колонка2>
			<Колонка3>исходник. таблица 1. строка1. колонка3</Колонка3>
			<Колонка4>исходник. таблица 1. строка1. колонка4</Колонка4>
		</Строка>
		<Строка>
			<Колонка1>исходник. таблица 1. строка2. колонка1</Колонка1>
			<Колонка2>исходник. таблица 1. строка2. колонка2</Колонка2>
			<Колонка3>исходник. таблица 1. строка2. колонка3</Колонка3>
			<Колонка4>исходник. таблица 1. строка2. колонка4</Колонка4>
		</Строка>
	</Таблица1>
	<Таблица3>
		<Строка>
			<Колонка1>исходник. таблица 3. колонка1</Колонка1>
			<Колонка2>исходник. таблица 3. колонка2</Колонка2>
			<Колонка3>исходник. таблица 3. колонка3</Колонка3>
		</Строка>
	</Таблица3>    
</CatalogObject.Организации>


Образец
<CatalogObject.Организации>
	<Поле1>образец поле1</Поле1>
	<Поле2>образец поле2</Поле2>
	<Поле4/>
	<Поле5>образец поле5</Поле5>
	<Таблица1>
		<Строка>
			<Колонка1>образец. таблица1. колонка1</Колонка1>
			<Колонка2>образец. таблица1. колонка2</Колонка2>
			<Колонка3>образец. таблица1. колонка3</Колонка3>
			<Колонка5>образец. таблица1. колонка5</Колонка5>
		</Строка>
	</Таблица1>
	<Таблица2>
		<Строка>
			<Колонка5>образец. таблица2. колонка5</Колонка5>
			<Колонка6>образец. таблица2. колонка6</Колонка6>
			<Колонка7>образец. таблица2. колонка7</Колонка7>
		</Строка>
	</Таблица2>
</CatalogObject.Организации>


Результат
<CatalogObject.Организации>
	<Поле1>исходник. поле1</Поле1>
	<Поле2>исходник. поле2</Поле2>
	<Поле4/>
	<Поле5>образец поле5</Поле5>
	<Таблица1>
		<Строка>
			<Колонка1>исходник. таблица 1. строка1. колонка1</Колонка1>
			<Колонка2>исходник. таблица 1. строка1. колонка2</Колонка2>
			<Колонка3>исходник. таблица 1. строка1. колонка3</Колонка3>
			<Колонка5>образец. таблица1. колонка5</Колонка5>
		</Строка>
		<Строка>
			<Колонка1>исходник. таблица 1. строка2. колонка1</Колонка1>
			<Колонка2>исходник. таблица 1. строка2. колонка2</Колонка2>
			<Колонка3>исходник. таблица 1. строка2. колонка3</Колонка3>
			<Колонка5>образец. таблица1. колонка5</Колонка5>
		</Строка>
	</Таблица1>
	<Таблица2>
		<Строка>
			<Колонка5>образец. таблица2. колонка5</Колонка5>
			<Колонка6>образец. таблица2. колонка6</Колонка6>
			<Колонка7>образец. таблица2. колонка7</Колонка7>
		</Строка>
	</Таблица2>
</CatalogObject.Организации>
  • Вопрос задан
  • 2619 просмотров
Пригласить эксперта
Ответы на вопрос 2
mututunus
@mututunus
Backend developer (Python, Golang)
Вам поможет XSLT.
Ответ написан
@llirikkkk
Делал похожую задачу, только поиск лишних/отсутствующих узлов и значений
Использовал C# -> System.Xml.Linq (ну или другое что по желанию)

1. обходим всё дерево образца и для каждого узла формируем путь к нему (какой-нить псевдо xpath)
например:
CatalogObject.Организации>Поле1=образец поле1
CatalogObject.Организации>Таблица1>Строка>Колонка1=исходник. таблица 1. строка1. колонка1
1.1. Cкладываем для упрощения последюющего доступа к ним в Dictionary(string, XElement)
2. обходим всё дерево исходника и аналогично формируем путь для каждого узла
3. потенциально все пути уникальны. ищем лишние/недостающие пути.
4. лишние из исходника удаляем, недостающие добавляем (берём из Dictionary)

в моём случае надо было проверять xml файлы на полное совпадение, поэтому в пути я использовал ещё и атрибуты(+ их значения) и значения непосредственно элементов
выглядело примерно так
корень>узел1@атрибут1=значение@атрибут2=значение=значениеУзла
или
корень>узел2>узел3@атрибут1=значение@атрибут2=значение>узел4=значениеУзла

если значения элементов могут не совпадать
тогда всё упирается в формирование уникального пути к каждому узлу
можно добавлять индексацию в пути для совпадающих элементов
CatalogObject.Организации>Таблица[10]>Строка[2]

P.S. написать возможный велосипед для меня приятнее, чем искать специфические готовые решения : )
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы