Как объединить два XML-файла, используя XSLT1.0 - PullRequest
0 голосов
/ 04 апреля 2019

Я пытаюсь объединить два XML-файла, используя XSLT1.0. Я пытаюсь объединить FileOne и Filetwo, чтобы объединить в новый файл XML. Результирующий xml должен содержать один элемент из файла два на основе значения из тега измерения. Любая помощь будет принята с благодарностью

Fileone.xml

<Schedule name="NE3S">
    <Item scheduleId="1" startDate="2013-01-01" stopDate="2037-12-31">
        <measurements>
            <measurement>PGW0001</measurement>
        </measurements>
        <measPeriods>
            <period day="0" duration="0" hour="0" interval="15" minutes="0"/>
        </measPeriods>
    </Item>
    <Item scheduleId="2" startDate="2013-01-01" stopDate="2037-12-31">
        <measurements>
            <measurement>PGW0002</measurement>
        </measurements>
        <measPeriods>
            <period day="0" duration="0" hour="0" interval="60" minutes="0"/>
        </measPeriods>
    </Item>
</Schedule>

Filetwo.xml

<Schedule name="NE3S">
    <Item scheduleId="1" startDate="2013-01-01" stopDate="2037-12-31">
        <measurements>
        <measurement>PGW0001</measurement>
    </measurements>
    <measPeriods>
        <period day="0" duration="0" hour="0" interval="60" minutes="0"/>
    </measPeriods>
    </Item>
    <Item scheduleId="2" startDate="2013-01-01" stopDate="2037-12-31">
        <measurements>
            <measurement>PGD0001</measurement>
        </measurements>
    <measPeriods>
        <period day="0" duration="0" hour="0" interval="60" minutes="0"/>
    </measPeriods>
    </Item>
    <Item scheduleId="3" startDate="2013-01-01" stopDate="2037-12-31">
        <measurements>
            <measurement>PGW0002</measurement>
        </measurements>
        <measPeriods>
            <period day="0" duration="0" hour="0" interval="60" minutes="0"/>
        </measPeriods>
    </Item>
</Schedule>

Мой ожидаемый результат -

<Schedule name="NE3S">
    <Item scheduleId="1" startDate="2013-01-01" stopDate="2037-12-31">
        <measurements>
            <measurement>PGW0001</measurement>
        </measurements>
        <measPeriods>
            <period day="0" duration="0" hour="0" interval="15" minutes="0"/>
        </measPeriods>
    </Item>
    <Item scheduleId="2" startDate="2013-01-01" stopDate="2037-12-31">
        <measurements>
            <measurement>PGD0001</measurement>
        </measurements>
        <measPeriods>
            <period day="0" duration="0" hour="0" interval="60" minutes="0"/>
        </measPeriods>
    </Item>
    <Item scheduleId="3" startDate="2013-01-01" stopDate="2037-12-31">
        <measurements>
            <measurement>PGW0002</measurement>
        </measurements>
        <measPeriods>
            <period day="0" duration="0" hour="0" interval="60" minutes="0"/>
        </measPeriods>
    </Item>
</Schedule>

обратите внимание, что ожидаемый результат

<measPeriods>
  <period day="0" duration="0" hour="0" interval="15" minutes="0"/>
</measPeriods>

Я попробовал следующий код

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="fileName" select="'/opt/Filetwo.xml'" />
<xsl:param name="updates" select="document($fileName)" />

<xsl:variable name="updateMeasurement" select="$updates/Schedule/Item" />

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Schedule">
    <xsl:copy>
      <xsl:apply-templates select="Item[not(measurements/measurement = $updateMeasurement/measurements/measurement)]" />
      <xsl:apply-templates select="/Schedule/Item//measurements" />
      <xsl:apply-templates select="$updates/Schedule/Item/measPeriods" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>


xsltproc merge.xslt /opt/Fileone.xml > /opt/FileThree.xml

мой ожидаемый вывод должен иметь тег <measPeriods> из Fileone.xml, если значение в <measurements>/<measurement> соответствует

отредактировал мое решение до

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0"
encoding="UTF-8" indent="yes"/>

<xsl:variable name="addresses"
select="document('/opt/esymac/extras/esymacstarter/schedule/MJ.netact.xml_backup')"/>
   <xsl:template match="/measSchedule">
        <measSchedule name="NE3S">
        <xsl:for-each select="scheduleItem">
           <xsl:variable name="id" select="@scheduleId"/>
           <xsl:variable name="startDate" select="@startDate"/>
           <xsl:variable name="stopDate" select="@stopDate"/>
           <xsl:variable name="day" select="measPeriods/period/@day"/>
           <xsl:variable name="duration" select="measPeriods/period/@duration"/>
           <xsl:variable name="hour" select="measPeriods/period/@hour"/>
           <xsl:variable name="minutes" select="measPeriods/period/@minutes"/>

           <xsl:variable name="interval"
select="$addresses/measSchedule/scheduleItem/measurements[$counterId =
@measurement]/measPeriods/@interval"/>
             <Item scheduleId="{$id}" startDate="{$startDate}" stopDate="{$stopDate}">
             <measurements>
                <measurement><xsl:value-of select="measurements/measurement"/></measurement>
             </measurements>
             <measPeriods>
                   <period day="{$day}" duration="{$duration}" hour="{$hour}" interval="{$interval}" minutes="{$minutes}"/>
             </measPeriods>
             </Item>
    </xsl:for-each>
</measSchedule>
</xsl:template>

</xsl:stylesheet>

теперь я правильно получаю метку предмета, но

<period day="{$day}" duration="{$duration}" hour="{$hour}" interval="{$interval}" minutes="{$minutes}"/>

все еще не правильно

1 Ответ

0 голосов
/ 08 апреля 2019

Из входных XML-файлов похоже, что Fileone.xml имеет подмножество записей из Filetwo.xml. Более простой подход - написать XSL и применить его к Filetwo.xml (поскольку в нем есть все записи, а нам нужно заменить только несколько) и получить доступ к Fileone.xml с помощью функции document().

Для соответствующего значения <measurement> вы можете использовать <xsl:choose></xsl:choose> для копирования period из Fileone.xml, а для несоответствующего значения сохранить period из Filetwo.xml. Ниже приведен блок <xsl:choose>.

<xsl:choose>
    <xsl:when test="$extSchedule/Item/measurements/measurement = current()/ancestor::Item/measurements/measurement">
        <xsl:copy-of select="$extSchedule/Item[measurements/measurement = current()/ancestor::Item/measurements/measurement]/measPeriods/period" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:apply-templates select="period" />
    </xsl:otherwise>
</xsl:choose>

Здесь current() используется для доступа к правильному узлу и соответствующему значению measurement его родного брата.

Полный XSLT как ниже

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" />
    <xsl:strip-space elements="*" />

    <xsl:param name="fileName" select="document('Fileone.xml')" />
    <xsl:variable name="extSchedule" select="$fileName/Schedule" />

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="measPeriods">
        <xsl:copy>
            <xsl:choose>
                <xsl:when test="$extSchedule/Item/measurements/measurement = current()/ancestor::Item/measurements/measurement">
                    <xsl:copy-of select="$extSchedule/Item[measurements/measurement = current()/ancestor::Item/measurements/measurement]/measPeriods/period" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="period" />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

В выводе ниже показано, что period для PGW0001 заменено на соответствующий узел из Fileone.xml.

<Schedule name="NE3S">
    <Item scheduleId="1" startDate="2013-01-01" stopDate="2037-12-31">
        <measurements>
            <measurement>PGW0001</measurement>
        </measurements>
        <measPeriods>
            <period day="0" duration="0" hour="0" interval="15" minutes="0" />
        </measPeriods>
    </Item>
    <Item scheduleId="2" startDate="2013-01-01" stopDate="2037-12-31">
        <measurements>
            <measurement>PGD0001</measurement>
        </measurements>
        <measPeriods>
            <period day="0" duration="0" hour="0" interval="60" minutes="0" />
        </measPeriods>
    </Item>
    <Item scheduleId="3" startDate="2013-01-01" stopDate="2037-12-31">
        <measurements>
            <measurement>PGW0002</measurement>
        </measurements>
        <measPeriods>
            <period day="0" duration="0" hour="0" interval="60" minutes="0" />
        </measPeriods>
    </Item>
</Schedule>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...