问题
this is my xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<products>
<product_id value=" 1 ">
<tab_id value=" 51 ">
<tab_name value=" test1 "/>
<status value=" 2 "/>
<log value=" 5748 , 5749 , 128 "/>
<born_from value=" 1980-08-01 , 1989-02-01 "/>
<born_to value=" 1985-08-01 , 1998-02-01 "/>
<sex value=" 2 , 1 "/>
<link value=" www.google.com "/>
</tab_id>
</product_id>
<product_id value=" 2 ">
<tab_id value=" 52 ">
<tab_name value=" test2 "/>
<status value=" 3 "/>
<log value=" 458 , 912 , 333 "/>
<registration value=" 2013-01-01 "/>
<born_from value=" 1995-01-25 , 1993-08-03 "/>
<born_to value=" 2000-01-25 , 2002-10-25 "/>
<sex value=" 1 , 1 "/>
<link value=" www.yahoo.com "/>
<label value=" open "/>
</tab_id>
</product_id>
<product_id value=" 3 ">
<tab_id value=" 54 ">
<tab_name value=" test3 "/>
<status value=" start "/>
<venue value=" US "/>
<born_from value=" 2000-01-01 , 2002-02-01 "/>
<born_to value=" 2005-01-01 , 2003-01-01 "/>
<sex value=" 1 , 2 "/>
<link value=" www.facebook.com "/>
</tab_id>
</product_id>
</products>
i have written this XSLT code to display all the data of product where the my_date
variable will compare between to dates of born_from and born_to and give the output data of product 1 & 2
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:param name="my_date" select="'1992-01-01'"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/products" priority="1">
<html>
<body>
<table border="1">
<tr>
<th>Product ID</th>
<th colspan="2">Product DATA</th>
</tr>
<xsl:apply-templates select="product_id/tab_id/born_from[@value > $my_date] | product_id/tab_id/born_to[@value < $my_date]"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="product_id/tab_id">
<tr>
<td>
<xsl:value-of select="product_id"/>
</td>
<td><xsl:value-of select="name(*[1])"/> --></td>
<td><xsl:value-of select="*[1]/*[1]"/></td>
</tr>
<xsl:apply-templates select="*[not(self::product_id)]"/>
</xsl:template>
<!--These 2 templates will handle the data on the same
row as the tab name.-->
<xsl:template match="product_id/tab_id/*[1]" priority="1">
<xsl:apply-templates mode="newrow"/>
</xsl:template>
<xsl:template match="product_id/tab_id/*[1]/*[1]" mode="newrow"/>
<xsl:template match="*" mode="newrow">
<xsl:call-template name="dataRow"/>
</xsl:template>
<xsl:template match="product_id/tab_id/*/*[not(position()=1)]">
<xsl:call-template name="dataRow"/>
</xsl:template>
<xsl:template name="dataRow">
<tr>
<td/>
<td/>
<td><xsl:value-of select="."/></td>
</tr>
</xsl:template>
<xsl:template match="*[not(self::node)]">
<tr>
<td/>
<td><xsl:value-of select="name()"/> --></td>
<td><xsl:apply-templates/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
i am beginner to date comparison there is something wrong
simply my_date
will compare like this
for product 1
1980-08-01 > my_date && my_date < 1985-08-01
1989-02-01 > my_date && my_date < 1998-02-01
for product 2
1995-01-25 > my_date && my_date < 2000-01-25
1993-08-03 > my_date && my_date < 2002-10-25
same for product 3
here my_date
compare with both first value then secound and so on.. i think here issue is comma separated values
i want my output like this
Product ID | Product DATA
--------------------------------
1 |product_id => 1
|tab_id => 51
|tab_name => test1
|status => 2
|log => 72
| 19
| 79
|born_from => 1980-08-01
| 1989-02-01
|born_to => 1985-08-01
| 1998-02-01
|sex => 2
| 1
|link => www.google.com
same for the product 2 with its value thanks in advance
回答1:
Before talking about dates, it should be noted there is another issue with your xsl:apply-templates
<xsl:apply-templates select="product_id/tab_id/born_from[@value > $my_date]" />
This will select born_from elements, but from looking at your matching templates it looks like you want to actually select the tab_id element, so you would have to re-write it like so:
<xsl:apply-templates select="product_id/tab_id[born_from/@value > $my_date]" />
However, as mentioned in the comment there is no in-built support for dates in XSLT 1.0. You would either have to use an exension function or upgrade to use XSLT 2.0.
However, if your dates are always going to be in YYYY-MM-DD format, you could do simple numeric comparison by removing the hyphens and treating them as 8 digit numbers.
First, create a variable to convert your my_date parameter into a number of the format YYYYMMDD
<xsl:variable name="comp_date" select="translate($my_date, '- ', '')" />
Then, try changing the subsequent xsl:apply-templates to this.
<xsl:apply-templates select="
product_id/tab_id[translate(substring-before(born_from/@value, ','), '- ', '') > $comp_date]|
product_id/tab_id[translate(substring-before(born_to/@value, ','), '- ', '') < $comp_date]"/>
Note the use of substring-before to extract only the first date before the comma in the @value attribute. If you also wanted to check the date after the comma, use substring-after.
来源:https://stackoverflow.com/questions/15217677/compare-date-between-two-dates-using-xslt