Объединить и обновить значения узлов двух XML-файлов с помощью xslt

Я новичок в XSLT. Но я считаю, что приведенное ниже требование может быть достигнуто с помощью XSLT :) Теперь у меня есть требование, когда мне нужно объединить 2 разных xml в один, и должна быть проверка, где xslt должен быть способен проверять имя узла, например, если input1/nodeName соответствует input2/nodeName, тогда значение должно быть заполнено из input2.

Например:

Ввод1 xml:

<Parent>
    <C1>123</C1>
    <C2>Incorrect data</C2>
    <C3>789</C3>
</Parent>

Вход2 xml:

<NewParent>
  <C2>CorrectData</C2>
</NewParent>

Вывод: должно быть

<Parent>
    <C1>123</C1>
    <C2>CorrectData</C2>
    <C3>789</C3>
</Parent>

Я попытался ниже XSLT объединить оба, но не нашел решения.

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:param name="input1" select="input1.xml" />
    <xsl:param name="input2" select="input2.xml" />
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/">
        <xsl:copy>
            <xsl:for-each select="/*">
                <xsl:choose>
                    <xsl:when
                        test="$input1//node() = $input2//node()">
                        <xsl:value-of select="$input2/node()" />
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="@* | node()" />
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

и таблица стилей завершается с некоторой ошибкой набора узлов.

Примечание. Чтобы получить результат, мы не должны указывать имя узла (например, c1, c2) нигде в коде XSLT. Он должен быть общим.

Пожалуйста, дайте мне знать, если потребуется дополнительная информация. А также дайте мне знать, если мой вопрос не ясен.


person Uday Shankar    schedule 04.02.2015    source источник
comment
Если у вас возникнут следующие вопросы, обратитесь к справке по форматированию: stackoverflow.com/editing-help#code.   -  person Mathias Müller    schedule 04.02.2015
comment
Попробуйте алгоритм слияния Оливера Беккера, прежде чем внедрять свой собственный: www2 .informatik.hu-berlin.de/~obecker/XSLT/merge/.   -  person Mathias Müller    schedule 04.02.2015


Ответы (1)


Попробуй это:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:variable name="input1" select="document('input1.xml')" />
<xsl:variable name="input2" select="document('input2.xml')" />
<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
</xsl:template>
<xsl:template match="/">
    <xsl:copy>
        <xsl:for-each select="$input1/*">
            <xsl:copy>
                <xsl:for-each select="*">
                    <xsl:choose>
                        <xsl:when test="name() = $input2//name()">
                            <xsl:copy-of select="$input2/*/node()" />
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:copy-of select="." />
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:for-each>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

Выход:

<Parent>
 <C1>123</C1>
 <C2>CorrectData</C2>
 <C3>789</C3>
</Parent>
person Rudramuni TP    schedule 04.02.2015
comment
Рудрамуни - спасибо за ответ. я попробовал обновление, которое вы предложили, но оно не обновляет полезную нагрузку, если я применю вышеуказанный xslt. вывод, который я получаю, такой же, как input1 xml (как вывод). - person Uday Shankar; 05.02.2015
comment
Удай, проверьте имена файлов, указанные в XSLT, относительно внешних имен файлов. - person Rudramuni TP; 05.02.2015
comment
Привет, Рудрамуни, прежде чем я скажу, что попробовал то, что вы сказали ... возможно ли для нас выполнить код xslt без указания физического местоположения входных xml внутри кода xslt? на самом деле я должен динамически передавать ввод xml (не извлекать из конкретного физического местоположения). поэтому xslt должен иметь возможность получать оба ввода (xmls) в param1 и param2 соответственно (это должно быть что-то вроде этого?), пожалуйста, дайте мне знать, если вам нужна дополнительная информация ... я пробовал много способов, но не нашел удачи . помоги мне в этом... - person Uday Shankar; 09.02.2015
comment
@UdayShankar, я также пытался использовать фиктивный входной XML, и XSLT извлекает информацию из двух других XML, которые расположены в пути к сценарию XSLT. Пожалуйста, опубликуйте новый вопрос с этим требованием, так как на нашем сайте Stackoverflow есть много экспертов, которые обязательно предложат вам правильный. Сработал ли этот XSLT для вас? - person Rudramuni TP; 09.02.2015
comment
Рудрамуни, да, это сработало для меня. но с некоторыми модификациями кода, на самом деле я хочу реализовать этот код в OSB. поэтому мне пришлось динамически передавать входные XML-файлы (не передавая входные данные с физическим расположением XML-файла). поэтому я должен представить java, который преобразует один из моих xml в объект DOM. поэтому этот xslt нуждается в некоторой модификации кода. в основном, чтобы сказать, что я взял часть кода XSLT из 1-го для каждого. благодаря тонну. :) - person Uday Shankar; 13.02.2015