Фон / Резюме:
у меня есть очень большой вложенный (Job-XML) XML. Мы выполняем процесс, который позволяет пользователям вносить изменения в данные (визуальный элемент XML), затем нам необходимо отобразить эти изменения обратно в XML, чтобы мы могли отправить обновление в XML обратно в исходную систему. Пользователь может изменить 1 вещь или 1 миллион вещей на любом уровне документа, который они видят.
Платформа, которую мы используем, которая позволяет пользователям вносить изменения, создает список тегов и их значений (Список изменений), которые пользователь изменил. мы сопоставили эти теги с исходным местоположением XML, но делать это в преобразователе Java будет громоздким и неинтересным в обслуживании.
в идеале я хочу сгенерировать XML из сторонней платформы XML (Change XML), которая имеет местоположения в исходном XML для обновления и идентификаторы, указывающие, какую часть исходного XML (Jobs XML) следует изменить.
Задача :
Для каждого из модов задан файл Changes.xml с модификациями - замените это поле в Jobs.xml значением этого мода, если этот элемент соответствует условиям идентификатора, вызванным в модификации.
Я уже подумал, что я могу динамически выбирать Xpath, учитывая список Xpath, и также обновлять это значение динамически. Который работает, ЕСЛИ не было условий на подбор, но есть.
Я могу использовать XSL 1-3, не имеет значения.
<?xml version="1.0" encoding="UTF-8"?>
<!--CHANGES.XML -->
<accounts>
<changes>
<modifications>
<modification>
<parentpath>accounts/locationArea/thisloc</parentpath>
<mods>
<mod>
<path>/accounts/locationArea/thisloc/jobs/job</path>
<field>salary</field>
<val>1000</val>
</mod>
</mods>
<identifiers>
<identifier>
<path>accounts/locationArea/thisloc</path>
<field>key</field>
<val>1</val>
</identifier>
<identifier>
<path>accounts/locationArea/thisloc/jobs/job</path>
<field>building</field>
<val>1</val>
</identifier>
<identifier>
<path>accounts/locationArea/thisloc/jobs/job</path>
<field>role</field>
<val>Kitchen</val>
</identifier>
</identifiers>
</modification>
<modification>
<parentpath>accounts/locationArea/thisloc</parentpath>
<mods>
<mod>
<path>/accounts/locationArea/thisloc</path>
<field>manager</field>
<val>Sam</val>
</mod>
<mod>
<path>/accounts/locationArea/thisloc</path>
<field>updated</field>
<val>true</val>
</mod>
</mods>
<identifiers/>
</modification>
</modifications>
</changes>
</accounts>
<?xml version="1.0" encoding="UTF-8"?>
<!--Jobs.XML, this is the one we need to edit -->
<accounts>
<locationArea>
<thisloc>
<title>locaton1</title>
<manager>Dean</manager>
<key>1</key>
<jobs>
<job>
<tag>1</tag>
<building>1</building>
<role>BA</role>
<salary>100</salary>
</job>
<job>
<tag>2</tag>
<building>1</building>
<role>IT</role>
<salary>200</salary>
</job>
<job>
<tag>3</tag>
<building>1</building>
<role>Kitchen</role>
<salary>300</salary>
</job>
</jobs>
</thisloc>
<thisloc>
<title>locaton2</title>
<manager>Smith</manager>
<updated>false</updated>
<key>2</key>
<jobs>
<job>
<tag>1</tag>
<building>1</building>
<role>Kitchen</role>
<salary>300</salary>
</job>
<job>
<tag>2</tag>
<building>2</building>
<role>Mail</role>
<salary>400</salary>
</job>
</jobs>
</thisloc>
</locationArea>
</accounts>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://myns">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="changesXML" select="doc('changes.xml')"/>
<xsl:variable name="changes" select="$changesXML/accounts/changes/modifications/modification/mods/mod"/>
<xsl:template name="dynomatch" match="*[$changes/path]/*[local-name()=$changes/field]/text()">
<xsl:value-of select="$changes/val"/>
</xsl:template>
</xsl:stylesheet>
Я хочу, чтобы результаты выглядели так:
- (1) «зарплата» для роли кухни для ТОЛЬКО ключа местоположения 1 была обновлена с 300 тоже 1000
- (2) «менеджер» для всех мест был изменен на «Сэм»
- и (3) значение «обновлено» было установлено в значение «истина» для всех местоположений и добавлено для тех, кто пропускал тег все вместе.
<?xml version="1.0" encoding="UTF-8"?>
<accounts>
<locationArea>
<thisloc>
<title>locaton1</title>
<manager>Sam</manager>
<updated>true</updated>
<key>1</key>
<jobs>
<job>
<tag>1</tag>
<building>1</building>
<role>BA</role>
<salary>100</salary>
</job>
<job>
<tag>2</tag>
<building>1</building>
<role>IT</role>
<salary>200</salary>
</job>
<job>
<tag>3</tag>
<building>1</building>
<role>Kitchen</role>
<salary>350</salary>
</job>
</jobs>
</thisloc>
<thisloc>
<title>locaton2</title>
<manager>Sam</manager>
<updated>true</updated>
<key>2</key>
<jobs>
<job>
<tag>1</tag>
<building>1</building>
<role>Kitchen</role>
<salary>300</salary>
</job>
<job>
<tag>2</tag>
<building>2</building>
<role>Mail</role>
<salary>400</salary>
</job>
</jobs>
</thisloc>
</locationArea>
</accounts>