2015-05-21 2 views
0

У меня есть 2 XML-файлы, как показано ниже:Объединить 2 XML-файлы с помощью XSLT в UNIX

File1.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Schedule name="myOffice"> 
    <taskItem taskId="1" startDate="2013-01-01" stopDate="2037-12-31"> 
    <measurements> 
     <measurement>USD</measurement> 
    </measurements> 
    <timings> 
     <period day="0" duration="0" hour="0" interval="28" minutes="0"/> 
    </timings> 
    </taskItem> 
    <taskItem taskId="2" startDate="2013-01-01" stopDate="2037-12-31"> 
    <measurements> 
     <measurement>Rupee</measurement> 
    </measurements> 
    <timings> 
     <period day="0" duration="0" hour="0" interval="15" minutes="0"/> 
    </timings> 
    </taskItem> 
</Schedule> 

File2.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Schedule name="myOffice"> 
    <taskItem taskId="1" startDate="2015-12-01" stopDate="2037-12-31"> 
    <measurements> 
     <measurement>Rupee</measurement> 
    </measurements> 
    <timings> 
     <period day="5" duration="10" hour="0" interval="20" minutes="0"/> 
    </timings> 
    </taskItem> 
</Schedule> 

Я используя XSLT для получения следующего выхода:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Schedule name="myOffice"> 
    <taskItem taskId="1" startDate="2013-01-01" stopDate="2037-12-31"> 
    <measurements> 
     <measurement>USD</measurement> 
    </measurements> 
    <timings> 
     <period day="0" duration="0" hour="0" interval="28" minutes="0"/> 
    </timings> 
    </taskItem> 
    <taskItem taskId="2" startDate="2013-01-01" stopDate="2037-12-31"> 
    <measurements> 
     <measurement>Rupee</measurement> 
    </measurements> 
    <timings> 
     <period day="5" duration="10" hour="0" interval="20" minutes="0"/> 
    </timings> 
    </taskItem> 
</Schedule> 

Но получить это как выход:

<Schedule name="myOffice"> 
    <taskItem taskId="1" startDate="2015-12-01" stopDate="2037-12-31"> 
    <measurements> 
     <measurement>Rupee</measurement> 
    </measurements> 
    <timings> 
     <period day="5" duration="10" hour="0" interval="20" minutes="0"/> 
    </timings> 
    </taskItem> 
</Schedule> 

Я не могу получить, где я отстающих ....

Моя идея, основанная на поле Measurement, я должен обновить атрибуты stopDate в taskItem, и day, duration, hour, interval, minutes в period бирка.

Мой файл XSLT является

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes" omit-xml-declaration="yes"/> 

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

    <xsl:template match="taskItem//measurement"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()" /> 
     <xsl:apply-templates 
     select="document('file1.xml') 
       /Schedule/taskItem/timings/period[@day = current()/../../timings/period/@day and 
               @duration = current()/../../timings/period/@duration and 
               @hour = current()/../../timings/period/@hour and 
               @interval = current()/../../timings/period/@interval and 
               @minutes = current()/../../timings/period/@minutes]/*" /> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Я уверен, выполнение команды в UNIX следующим образом:

xsltproc xs.xslt file2.xml 

ответ

1

Я думаю вы хотите сделать:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output indent="yes" omit-xml-declaration="yes"/> 

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

<xsl:template match="timings"> 
    <xsl:variable name="match" select="document('file2.xml')/Schedule/taskItem[measurements/measurement=current()/../measurements/measurement]/timings"/> 
    <xsl:choose> 
     <xsl:when test="$match"> 
      <xsl:copy-of select="$match"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:copy-of select="."/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

</xsl:stylesheet> 

и указать file1.xml как файл для обработки.

+0

спасибо за ответ, но выход, который я получил, не имел заголовка .... как я могу включить .... этот напрямую с помощью XSLT ....

+1

Я думал, что вы не хотите декларации XML, потому что ваш XSLT явно опускает его, и я скопировал это. Если вы этого захотите, удалите атрибут 'omit-xml-declaration =" yes "' из инструкции 'xsl: output' (или измените его значение на" yes "). –

+0

этот только добавляет '', Но если я хочу полный заголовок, '' , то что мне делать –

1

Это мое (подробное) решение из того, что я понял. Я явно обновляю все атрибуты/поля, чтобы вы могли настроить это решение, чтобы адаптировать его к вашим потребностям. TaskId и startDate из объекта taskItem берутся из файла file1.xml. StopDate и тайминги берутся из файла file2.xml. Вы должны назвать этот лист XSLT параметром file1.xml.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes" omit-xml-declaration="yes"/> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()" /> 
    </xsl:copy> 
    </xsl:template> 
    <!-- For all taskItem in file1.xml --> 
    <xsl:template match="taskItem"> 
    <!-- Get all taskItems from file2.xml --> 
    <xsl:variable name="tiother" select="document('file2.xml')/Schedule/taskItem" /> 
    <!-- Get measurement text from current and other taskItems (from file1.xml and file2.xml) --> 
    <xsl:variable name="namethis" select="./measurements/measurement/text()" /> 
    <xsl:variable name="nameother" select="$tiother/measurements/measurement/text()" /> 
    <xsl:choose> 
     <!-- if the measurement texts are the same --> 
     <xsl:when test="$namethis = $nameother"> 
     <!-- Yes ? create a new taskItem updated --> 
     <xsl:element name="taskItem"> 
      <!-- Get taskId from the current task item (the one in file1.xml) --> 
      <xsl:attribute name="taskId"><xsl:value-of select="./@taskId"/></xsl:attribute> 
      <!-- Get startDate from the current task item (the one in file1.xml) --> 
      <xsl:attribute name="startDate"><xsl:value-of select="./@startDate"/></xsl:attribute> 
      <!-- Get stopDate from the other task item (the one in file2.xml) --> 
      <xsl:attribute name="stopDate"><xsl:value-of select="$tiother/@stopDate"/></xsl:attribute> 
      <!-- Get the measurements from the current task item (the one in file1.xml) --> 
      <xsl:copy-of select="./measurements"/> 
      <!-- Get the timings from the other task item (the one in file2.xml) --> 
      <xsl:copy-of select="$tiother/timings"/> 
     </xsl:element> 
     </xsl:when> 
     <xsl:otherwise> 
     <!-- No ? just copy the current taskItem --> 
     <xsl:copy-of select="."/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 
Смежные вопросы