0

I have 2 XML files as shown below:

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>

I am using XSLT to get the following output:

<?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>

But getting this as output:

<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>

I am not able to get where I am lagging....

My idea is, based on field Measurement, I have to update attributes stopDate in taskItem, and day,duration,hour,interval,minutes in period tag.

My XSLT file is

<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>

I am executing the command in unix as follows:

xsltproc xs.xslt file2.xml

2 Answers 2

1

I think you want to do:

<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>

and specify file1.xml as the file to be processed.

Sign up to request clarification or add additional context in comments.

4 Comments

thanks for the answer, but the output which I got was not having header....how can I include ....this one directly by XSLT....<?xml version="1.0" encoding="UTF-8" standalone="no"?>
I thought you didn't want the XML declaration, because your XSLT explicitly omits it and I copied that. If you do want it, remove the omit-xml-declaration="yes" attribute from the xsl:output instruction (or change its value to "yes").
this one is adding only <?xml version="1.0"?>, but if I want complete header, <?xml version="1.0" encoding="UTF-8" standalone="no"?>, then what should I do
Make your xsl:output instruction <xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="no" indent="yes"/>.
1

This is my (verbose) solution from what I understood. I explicitly update each attributes/fields so you can tweak this solution to adapt it to your needs. The taskId and startDate from the taskItem are taken from file1.xml. The stopDate and timings are take from file2.xml. You must call this XSLT sheet with file1.xml as parameter.

 <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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.