XSL 如何找到特定日期的儒略日?

XSL how to find the Julian day for a specific date?

我有这个简单的 XML-文件

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="faan.xsl"?>
<datum>2016-05-17</datum>

我想使用 XSL(XSL 2.0 和扩展不是一个选项)来计算这个日期的儒略日(正确答案是 2457526,这只是练习!)并想出了这种风格 sheet这似乎在许多地方都是复制粘贴的。 但是,当在资源管理器中打开文件时,它只会给我日期 2016-05-17,当我在 Excel 中打开它时,它说我不能在这个地方使用 xsl:with-param。 我显然错过了一些非常简单的东西,但是什么?

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

<xsl:template match="/">
    <xsl:for-each select="datum">
    <xsl:sort select="datum"/>
            <dateline>
                <datum><xsl:value-of select="datum"/></datum>
            </dateline>
    </xsl:for-each>
</xsl:template>

<xsl:template match="datum">
    <xsl:call-template name="calculate-julian-day" />
        <xsl:with-param name="year" select="substring(datum,1,4)" />
        <xsl:with-param name="month" select="substring(datum,6,2)" />
        <xsl:with-param name="day" select="substring(datum,9,2)" />
</xsl:template>

<xsl:template name="calculate-julian-day">
    <xsl:param name="year"/>
    <xsl:param name="month"/>
    <xsl:param name="day"/>

    <xsl:variable name="a" select="floor((14 - $month) div 12)"/>
    <xsl:variable name="y" select="$year + 4800 - $a"/>
    <xsl:variable name="m" select="$month + 12 * $a - 3"/>

    <xsl:value-of select="$day + floor((153 * $m + 2) div 5) + $y * 365 + floor($y div 4) - floor ($y div 100) + floor($y div 400) - 32045"/>
</xsl:template>

</xsl:stylesheet>

这是一种可能的解决方案

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


  <xsl:template match="datum">
    <xsl:call-template name="date-to-julian-day">
      <xsl:with-param name="date" select="."/>
    </xsl:call-template>
  </xsl:template>

<!--
==========================================================================
    Template: date-to-julian-day
 Description: Convert a date to julian day
 Parameters:-
    <year> <month> <day>
   or
    <date> (format: yyyymmdd or yyyy-mm-dd)
========================================================================== -->
    <xsl:template name="date-to-julian-day">
        <xsl:param name="year"/>
        <xsl:param name="month"/>
        <xsl:param name="day"/>
        <!-- or -->
        <xsl:param name="date" select="''"/>
        <!-- trim down date -->
        <xsl:variable name="tdate" select="translate($date,'-','')"/>
        <!-- decide which params were passed -->
        <xsl:variable name="yyyy">
           <xsl:choose>
             <xsl:when test="string-length($date) &gt; 0">
               <xsl:value-of select="substring($tdate,1,4)"/>
             </xsl:when>
             <xsl:otherwise><xsl:value-of select="$year"/></xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="mm">
            <xsl:choose>
              <xsl:when test="string-length($date) &gt; 0">
                <xsl:value-of select="substring($tdate,5,2)"/>
              </xsl:when>
              <xsl:otherwise><xsl:value-of select="$month"/></xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="dd">
            <xsl:choose>
                <xsl:when test="string-length($date) &gt; 0">
                   <xsl:value-of select="substring($tdate,7,2)"/>
                </xsl:when>
                <xsl:otherwise><xsl:value-of select="$day"/></xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <!-- pre-calcs -->
        <xsl:variable name="j0" select="ceiling(($mm - 14) div 12)"/>
        <xsl:variable name="j1" select="floor((1461 * ($yyyy + 4800 + $j0)) div 4)"/>
        <xsl:variable name="j2" select="floor((367 * ($mm - 2 - (12 * $j0))) div 12)"/>
        <xsl:variable name="j3" 
                      select="floor((3 * floor(($yyyy + 4900 + $j0) div 100)) div 4)"/>
        <!-- final calc -->
        <xsl:value-of select="$j1 + $j2 - $j3 + $dd - 32075"/>
    </xsl:template>

</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<datum>2016-05-17</datum>

产生了想要的、正确的结果:

2457526

归因:

所提供的代码是 datetime_lib.xsl XSLT 1.0 日期时间算术和转换模板库的一部分,由我的朋友 Martin Rowlinson(XSelerator 的作者)编写,是有史以来最好的 XSLT IDE,依然是易用性强的光辉典范UI。

有时在 2010 年左右,XSelerator 在 sourceforge.net 上免费提供,这就是人们通常获取这些有价值的模板库的方式..