Compare date between two dates using XSLT

拟墨画扇 提交于 2020-01-15 03:08:08

问题


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 &gt; $my_date] | product_id/tab_id/born_to[@value &lt; $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 &gt; $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 &gt; $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, ','), '- ', '') &gt; $comp_date]| 
product_id/tab_id[translate(substring-before(born_to/@value, ','), '- ', '') &lt; $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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!