Hi,
i have the folwing xml, i want to compare the dates Modifyts and ActualDate using XPATH and XSLT and print the date which is newer.Can you please help me regarding this.

<ABC>
    <InputDocument>
        <OrderList LastOrderHeaderKey="2011013111595948350"
            LastRecordSet="Y" ReadFromHistory="" TotalOrderList="1">
            <Order DocumentType="0001" EnterpriseCode="XYZ"
                Modifyts="2011-02-14T13:53:04+00:00" OrderNo="Y100000042"/>
        </OrderList>
    </InputDocument>
    <EnvironmentDocument>
        <Order DocumentType="0001" EnterpriseCode="XYZ"
            MaximumRecords="5000" OrderNo="Y100000042">
            <OrderDates>
                <OrderDate ActualDate="2011-02-15T08:12:13.5551986Z" DateTypeId="ACK_DATETIME"/>
            </OrderDates>
        </Order>
    </EnvironmentDocument>
<ABC>

Thanks
Soumya

Recommended Answers

All 8 Replies

Are you using XSLT 1.0 or 2.0 ?

Are you using XSLT 1.0 or 2.0 ?

m using 1.0

this is sample

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output indent="yes" method="xml"/>
	<xsl:template match="/">
		<root>
			<xsl:apply-templates select="ABC"/>
		</root>
	</xsl:template>


	<xsl:template match="ABC">

		<xsl:variable name="year" select="substring-before(InputDocument/OrderList/Order/@Modifyts,'-')"/>
		<xsl:variable name="month" select="substring-before(substring-after(InputDocument/OrderList/Order/@Modifyts,concat($year,'-')),'-')"/>
		<xsl:variable name="day" select="substring-before(substring-after(InputDocument/OrderList/Order/@Modifyts,concat($month,'-')),'T')"/>
		<xsl:variable name="time" select="substring(substring-after(InputDocument/OrderList/Order/@Modifyts,concat($day,'T')),1,8)"/>

		<xsl:variable name="oyear" select="substring-before(EnvironmentDocument/Order/OrderDates/OrderDate/@ActualDate,'-')"/>
		<xsl:variable name="omonth" select="substring-before(substring-after(EnvironmentDocument/Order/OrderDates/OrderDate/@ActualDate,concat($oyear,'-')),'-')"/>
		<xsl:variable name="oday" select="substring-before(substring-after(EnvironmentDocument/Order/OrderDates/OrderDate/@ActualDate,concat($omonth,'-')),'T')"/>
		<xsl:variable name="otime" select="substring(substring-after(EnvironmentDocument/Order/OrderDates/OrderDate/@ActualDate,concat($oday,'T')),1,8)"/>

		<oderlist>
			<year>
				<xsl:value-of select="$year"/>
			</year>
			<month>
				<xsl:value-of select="$month"/>
			</month>
			<day>
				<xsl:value-of select="$day"/>
			</day>
			<time>
				<xsl:value-of select="$time"/>
			</time>
		</oderlist>
		<order>
			<year>
				<xsl:value-of select="$oyear"/>
			</year>
			<month>
				<xsl:value-of select="$omonth"/>
			</month>
			<day>
				<xsl:value-of select="$oday"/>
			</day>
			<time>
				<xsl:value-of select="$otime"/>
			</time>
		</order>


		<test>
		<compareday>
<xsl:choose>
<xsl:when test="$oday &lt; $day">
<xsl:text>old order</xsl:text>
</xsl:when>
<xsl:when test="$oday &gt; $day">
<xsl:text>new order</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>equale</xsl:text>
</xsl:otherwise>
</xsl:choose>


</compareday>
		</test>
	</xsl:template>
</xsl:stylesheet>

result

<?xml version='1.0' ?>
<root>
  <oderlist>
    <year>2011</year>
    <month>02</month>
    <day>14</day>
    <time>13:53:04</time>
  </oderlist>
  <order>
    <year>2011</year>
    <month>02</month>
    <day>15</day>
    <time>08:12:13</time>
  </order>
  <test>
    <compareday>new order</compareday>
  </test>
</root>

If you're using XSLT 1.0, you can also use the extension functions that are on the EXSLT.org site for date manipulation. They've very simple and easy to use. There's a date:difference() function that allows you to easily subtract dates. Then you can just compare the output and print which you want.

http://www.exslt.org/date/index.html

If you're using XSLT 1.0, you can also use the extension functions that are on the EXSLT.org site for date manipulation. They've very simple and easy to use. There's a date:difference() function that allows you to easily subtract dates. Then you can just compare the output and print which you want.

http://www.exslt.org/date/index.html

thanks a lot andrews....that was really kind of you....and your replies were really helpful..thanks a lot man.....

If you're using XSLT 1.0, you can also use the extension functions that are on the EXSLT.org site for date manipulation. They've very simple and easy to use. There's a date:difference() function that allows you to easily subtract dates. Then you can just compare the output and print which you want.

http://www.exslt.org/date/index.html

btw...have you used cooktop??do u know how the xpath console works?
and can i get the dates using xpath and then compare them?

I'm not familiar with Cooktop as an IDE. I use Stylus Studio and Altova XML Spy for all my needs. As for your questions about XPath to compare them....

In XSLT and XPath 1.0, there is no data type for "date". There's basically strings and numbers. Therefore there are no methods or functions that do any kind of date manipulation. It's just not possible to do directly. That's why in "xml_looser"'s solution he had to break up the string into sections that could be compared like numbers. That's also why people created the EXSLT library. There was a common need to handle dates and various other things that weren't easily done in 1.0. So they created a library of usable components to use as part of their 1.0 solutions.

Once 2.0 came around all this date stuff became simple. "Date" is a real data type in 2.0 and there's a ton of built functions available in 2.0 that could do this in basically one line of code. Unfortunately, in 1.0 almost all date math is hard to do.

So here's another way to do what you want to do. If you go to EXSLT and download the dates package. Look for for the "date.difference.xsl" file in the functions directory. Once you pull this out, you can import into the XSLT below. Look at the implementation of that function on the EXSLT site, and this should make sense.

INPUT

<ABC>
	<InputDocument>
		<OrderList LastOrderHeaderKey="2011013111595948350" LastRecordSet="Y" ReadFromHistory="" TotalOrderList="1">
			<Order DocumentType="0001" EnterpriseCode="XYZ" Modifyts="2011-02-14T13:53:04+00:00" OrderNo="Y100000042"/>
		</OrderList>
	</InputDocument>
	<EnvironmentDocument>
		<Order DocumentType="0001" EnterpriseCode="XYZ" MaximumRecords="5000" OrderNo="Y100000042">
			<OrderDates>
				<OrderDate ActualDate="2011-02-15T08:12:13.5551986Z" DateTypeId="ACK_DATETIME"/>
			</OrderDates>
		</Order>
	</EnvironmentDocument>
</ABC>

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date">

	<xsl:import href="functions/difference/date.difference.xsl"/>

	<xsl:template match="/">
		<xsl:variable name="formatDate1" select="substring(ABC/InputDocument/OrderList/Order/@Modifyts, 1, 19)"/>
		<xsl:variable name="formatDate2" select="substring(ABC/EnvironmentDocument/Order/OrderDates/OrderDate/@ActualDate, 1, 19)"/>

		<xsl:variable name="getdiff">
			<xsl:call-template name="date:difference">
				<xsl:with-param name="start" select="$formatDate1"/>
				<xsl:with-param name="end" select="$formatDate2"/>
			</xsl:call-template>
		</xsl:variable>
		
		<xsl:choose>
			<xsl:when test="starts-with(string($getdiff), '-')" >
				<xsl:value-of select="ABC/InputDocument/OrderList/Order/@Modifyts" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="ABC/EnvironmentDocument/Order/OrderDates/OrderDate/@ActualDate" />
			</xsl:otherwise>
		</xsl:choose>

	</xsl:template>


</xsl:stylesheet>

The output is the date which is sooner.

2011-02-15T08:12:13.5551986Z

I'm not familiar with Cooktop as an IDE. I use Stylus Studio and Altova XML Spy for all my needs. As for your questions about XPath to compare them....

In XSLT and XPath 1.0, there is no data type for "date". There's basically strings and numbers. Therefore there are no methods or functions that do any kind of date manipulation. It's just not possible to do directly. That's why in "xml_looser"'s solution he had to break up the string into sections that could be compared like numbers. That's also why people created the EXSLT library. There was a common need to handle dates and various other things that weren't easily done in 1.0. So they created a library of usable components to use as part of their 1.0 solutions.

Once 2.0 came around all this date stuff became simple. "Date" is a real data type in 2.0 and there's a ton of built functions available in 2.0 that could do this in basically one line of code. Unfortunately, in 1.0 almost all date math is hard to do.

So here's another way to do what you want to do. If you go to EXSLT and download the dates package. Look for for the "date.difference.xsl" file in the functions directory. Once you pull this out, you can import into the XSLT below. Look at the implementation of that function on the EXSLT site, and this should make sense.

INPUT

<ABC>
	<InputDocument>
		<OrderList LastOrderHeaderKey="2011013111595948350" LastRecordSet="Y" ReadFromHistory="" TotalOrderList="1">
			<Order DocumentType="0001" EnterpriseCode="XYZ" Modifyts="2011-02-14T13:53:04+00:00" OrderNo="Y100000042"/>
		</OrderList>
	</InputDocument>
	<EnvironmentDocument>
		<Order DocumentType="0001" EnterpriseCode="XYZ" MaximumRecords="5000" OrderNo="Y100000042">
			<OrderDates>
				<OrderDate ActualDate="2011-02-15T08:12:13.5551986Z" DateTypeId="ACK_DATETIME"/>
			</OrderDates>
		</Order>
	</EnvironmentDocument>
</ABC>

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date">

	<xsl:import href="functions/difference/date.difference.xsl"/>

	<xsl:template match="/">
		<xsl:variable name="formatDate1" select="substring(ABC/InputDocument/OrderList/Order/@Modifyts, 1, 19)"/>
		<xsl:variable name="formatDate2" select="substring(ABC/EnvironmentDocument/Order/OrderDates/OrderDate/@ActualDate, 1, 19)"/>

		<xsl:variable name="getdiff">
			<xsl:call-template name="date:difference">
				<xsl:with-param name="start" select="$formatDate1"/>
				<xsl:with-param name="end" select="$formatDate2"/>
			</xsl:call-template>
		</xsl:variable>
		
		<xsl:choose>
			<xsl:when test="starts-with(string($getdiff), '-')" >
				<xsl:value-of select="ABC/InputDocument/OrderList/Order/@Modifyts" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="ABC/EnvironmentDocument/Order/OrderDates/OrderDate/@ActualDate" />
			</xsl:otherwise>
		</xsl:choose>

	</xsl:template>


</xsl:stylesheet>

The output is the date which is sooner.

2011-02-15T08:12:13.5551986Z

Thanks a ton Andrews..your replies where really really helpful....Thanks a lot.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.