Нужен XSLT для объединения двух XML-файлов - PullRequest
0 голосов
/ 15 ноября 2018

Структура файла: И File1.xml, и File2.xml имеют одинаковую структуру.

Файл имеет список / массив ресурсов, а каждый ресурс имеет список / массив кодов.

Каждый код уникально идентифицируется атрибутом «id».

Каждый код имеет атрибут override, который определяет правило переопределения.

Если override = "true", то элемент кода в file1.xml можно заменить на элемент кода в file2.xml.

Я хочу объединить File1.xml с File2.xml, используя xslt с нижеследующими правилами

  1. Если оба файла имеют одно и то же имя ресурса (например, «resource1»), тогда эти коды можно объединить.

    Во время операции слияния, если у нас одинаковое значение "id", тогда элемент кода file1 можно заменить ТОЛЬКО элементом code file2, когда override = "true".

    <code id="1" field1="value11" field2="value12" override="true" />
    <code id="1" field1="value71" field2="value72" override="true" />
    
    For this the result should be 
    <code id="1" field1="value71" field2="value72" override="true" /> 
    

    Если override = "false", то мы не заменяем элемент кода.

    Для этого результат должен быть

  2. Если у нас есть разные имена ресурсов (например, resource2 в File1.xml и resource3 в File2.xml), то их можно записать так, как они есть в output.xml, как нечего объединять файлы.

    Большое спасибо за проявленный интерес к моему вопросу !!!

File1.xml

<resources>
    <resource name="resource1">
        <codes>
            <code id="1" field1="value11" field2="value12" override="true" />
            <code id="2" field1="value21" field2="value22" override="false" />
            <code id="3" field1="value31" field2="value32" override="true" />
        </codes>
    </resource>
    <resource name="resource2">
        <codes>
            <code id="1" field1="value11" field2="value12" override="true" />
        </codes>
    </resource>
</resources>

File2.xml

<resources>
    <resource name="resource1">
        <codes>
            <code id="1" field1="value71" field2="value72" override="true" />
            <code id="2" field1="value81" field2="value82" override="true" />
            <code id="4" field1="value91" field2="value92" override="true" />
        </codes>
    </resource>
    <resource name="resource3">
        <codes>
            <code id="2" field1="value81" field2="value82" override="true" />
        </codes>
    </resource>
</resources>

output.xml

<resources>
    <resource name="resource1">
        <codes>
            <code id="1" field1="value71" field2="value72" override="true" />
            <code id="2" field1="value21" field2="value22" override="false" />
            <code id="3" field1="value31" field2="value32" override="true" />
            <code id="4" field1="value91" field2="value92" override="true" />
        </codes>
    </resource>
    <resource name="resource2">
        <codes>
            <code id="1" field1="value11" field2="value12" override="true" />
        </codes>
    </resource>
    <resource name="resource3">
        <codes>
            <code id="2" field1="value81" field2="value82" override="true" />
        </codes>
    </resource>
</resources>

1 Ответ

0 голосов
/ 17 ноября 2018

Поскольку вы, похоже, используете Java для запуска XSLT, вы можете рассмотреть возможность использования Saxon 9 (доступно для Java в HE-выпуске с открытым исходным кодом на Maven (текущая последняя версия Saxon 9.9 HE в https://search.maven.org/artifact/net.sf.saxon/Saxon-HE/9.9.0-2/jar, Saxon)9,8 HE в https://search.maven.org/artifact/net.sf.saxon/Saxon-HE/9.8.0-14/jar) и Sourceforge https://sourceforge.net/projects/saxon/files/Saxon-HE/), чтобы затем использовать XSLT 3 или 2 вместо двадцатилетнего XSLT 1, поддерживаемого встроенным процессором Oracle / Apache Xalan.

ИспользованиеВ XSLT 3 вы можете рассматривать это как проблему вложенных группировок следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:param name="doc2">
<resources>
    <resource name="resource1">
        <codes>
            <code id="1" field1="value71" field2="value72" override="true" />
            <code id="2" field1="value81" field2="value82" override="true" />
            <code id="4" field1="value91" field2="value92" override="true" /> 
        </codes>
    </resource>
    <resource name="resource3">
        <codes>
            <code id="2" field1="value81" field2="value82" override="true" />
        </codes>
    </resource>
</resources>
  </xsl:param>

  <xsl:output indent="yes"/>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="resources">
      <xsl:copy>
          <xsl:for-each-group select="resource, $doc2/resources/resource" group-by="@name">
              <resource>
                  <xsl:apply-templates select="@*"/>
                  <codes>
                      <xsl:for-each-group select="current-group()!codes/code" group-by="@id">
                          <xsl:apply-templates
                            select="if (current-group()[2] and ./@override = 'true')
                                    then current-group()[2]
                                    else ."/>
                      </xsl:for-each-group>
                  </codes>
              </resource>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / jyH9rNn / 3 имеет онлайн-образец для компактности и полнотыпримера второй документ используется как встроенный параметр, но, конечно, вы можете передать URI второго файла и использовать, например, <xsl:param name="doc2" select="doc("file2.xml")"/>.

Что касается введения в XSLT, бесплатная книга "Практическое руководство"Преобразование с использованием XSLT и XPath "доступно по адресу https://cranesoftwrights.github.io/books/ptux/index.htm.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...