【问题标题】:Using non-core EXSLT date functions with Xalan Java在 Xalan Java 中使用非核心 EXSLT 日期函数
【发布时间】:2014-03-31 15:25:48
【问题描述】:

EXSLT 的核心日期函数在我使用多年的一些 XSL 模板中运行良好。我想开始使用一个新的:seconds。此功能不是“核心”功能之一,因此实施可以声称符合 EXSLT 而无需实际实施。

我正在使用带有 Xalan 2.7.1 的 Cocoon 2.1.11,它似乎选择不实现 date:seconds

幸运的是,EXSLT 的好心人提供了下载来帮助您插入单个功能,但我似乎无法弄清楚如何实际实现该插件。

例如,我可以使用此模板轻松使用核心功能:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:date="http://exslt.org/dates-and-times" >
  <xsl:template match="/">
    <xsl:value-of select="date:date-time()" />
  </xsl:template>
</xsl:stylesheet>

在尝试使用date.seconds 函数时,我尝试了以下方法:

  1. 只需将&lt;xsl:import href="date.seconds.xsl" /&gt; 添加到我的模板中,然后使用date:seconds()。这让我收到错误消息“对于扩展功能,找不到方法 org.apache.xalan.lib.ExsltDatetime.seconds”
  2. 如上所示删除xmlns:date。这让我收到错误“前缀必须解析为命名空间:日期”
  3. date.seconds.xsl 的内容放在我要编写的模板中,然后不带参数调用date:seconds()(默认情况下它被定义为使用当前时间)。我收到此错误消息:“对方法秒的实例方法调用需要一个对象实例作为第一个参数”。现在看起来很有希望。
  4. date:seconds 添加一个参数。我收到错误消息:“对于扩展函数,找不到方法 java.lang.String.seconds([ExpressionContext,] )”

对于如何使用这个非核心的 EXSLT 函数有什么建议吗?

这是我当前的模板,仍然告诉我它正在尝试调用java.lang.String.seconds()

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:func="http://exslt.org/functions"
    xmlns:date="http://exslt.org/dates and times">
  <xsl:import href="date.seconds.xsl" />
  <func:script language="exslt:javascript" implements-prefix="date" src="date.js"/>
  <func:script language="exslt:msxsl" implements-prefix="date" src="date.msxsl.xsl"/>

  <xsl:template match="/">
    <xsl:value-of select="date:seconds('2014-02-27')" />
  </xsl:template>
</xsl:stylesheet>

【问题讨论】:

    标签: xslt xalan exslt


    【解决方案1】:

    对于那些想要自己滚动的人(特别是seconds()),可以使用以下代码来完成:

    package tools;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.text.ParseException;
    
    public class Dates
    {
      /**
       * Converts a date in xs:dateTime format into seconds-since-the-epoch
       * 
       * @param date The date to be converted,
       *             in <code>s:dateTime</code> format (yyyy-MM-dd'T'hh:mm:ss).
       *
       * @return Number of seconds since <code>1970-01-01 00:00:00</code>,
       *         or 0 if the date is blank or null.
       * @throws ParseException
       */
      public static long seconds(String date)
          throws ParseException
      {
          if(null == date || 0 == date.trim().length()) return 0;
    
          SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
          Date d = df.parse(date);
    
          return d.getTime() / 1000;
      }
    }
    

    这可以通过 Apache Xalan 像这样使用:

    <?xml ...
      xmlns:java="http://xml.apache.org/xalan/java"
      ...
    
    <xsl:variable name="some-date" select="...some xs:dateTime data ..." />
    <xsl:value-of select="java:tools.Dates.seconds($some-date)" />
    

    我可能会查看 Xalan 源代码以使其更灵活,但现在它似乎正在做我想做的事情。

    【讨论】:

      【解决方案2】:

      首先,看看:http://www.exslt.org/howto.html#other-implementations 但是,AFAIK Xalan 不支持 func:script 扩展元素(至少它它不支持,这并不总是相同的) . OTOH,Xalan 有自己的扩展机制 - 见:http://xml.apache.org/xalan-j/extensions.html

      如果是我,我会简单地使用命名模板。

      【讨论】:

      • 作为一个 hack,我最终使用了 Xalan 的 Java 语言绑定并编写了自己的简单函数来执行此操作。奇怪的是,ESXLT 提供的命名模板只是使用 &lt;func:script&gt; 东西定义了函数,所以它对我同样无效。
      • 你为什么不把它写下来作为答案并在这里发布呢?它可能对希望追随您的脚步的人有用。如果它遵循 Xalan 的配方,不知道你为什么称它为 hack。
      • Hack = 必须编写我自己的 Java 代码,此时应该有一个完美可用的后备实现。我不是想重新发明轮子。我将发布我的解决方案只是为了好玩,但我仍然想知道如何使用 EXSLT 的后备。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-22
      • 1970-01-01
      • 1970-01-01
      • 2016-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多