0

我正在使用 Saxon XSLT 处理器“来自 Saxonica 的 Saxon 9.0.0.2J”的开源版本,并且正在尝试第一次使用 java 可扩展性。我遇到了一个问题,我怀疑可能是对开源版本的限制,但我想先检查一下我是否在这里遗漏了一些东西。

从下面的片段中,我的结果是 $c1 的最终值不会因为调用 greg:setTime() 而改变 - 即 Saxon 中的 $c1 变量似乎与底层 Java 对象脱钩,并且存在没有明显的方法来访问由 setTime() 调用更新的对象。

请注意,片段中的所有代码都经过测试并且可以正常工作 - 即 $c1 已通过 getInstance() 调用正确实例化, $startdate 具有正确的格式,并且 $d1 已正确实例化。

想法?

<xsl:transform
       .....
       xmlns:sql="java:java.sql.Date"
       xmlns:greg="java:java.util.GregorianCalendar"
       .....
>
....
<xsl:element name="JobExpireDate">
      <xsl:variable name="c1" select="greg:getInstance()" />
      <xsl:variable name="d1" select="sql:valueOf($startdate)" />
      <xsl:variable name="void" select="greg:setTime($c1,$d1)" />
      <xsl:value-of select="$c1" />
</xsl:element>
4

2 回答 2

1

我刚刚尝试使用 saxonb9-0-0-8j。

有时会忽略对 void 函数的调用,如下所示。

输入文件:

<root>
<date1>2009-01-02</date1>
<date2>2009-01-02</date2>
</root>

变换:

 <xsl:transform
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns:sql="java:java.sql.Date"
       xmlns:greg="java:java.util.GregorianCalendar"
 version="2.0">

<xsl:template match="*">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

<xsl:template match="root/date1/text()">
      <xsl:variable name="c1" select="greg:getInstance()" />
      <xsl:variable name="d1" select="sql:valueOf(.)" />
      <xsl:variable name="void" select="greg:setTime($c1,$d1)" />
      <xsl:value-of select="greg:getTime($c1)" />
</xsl:template>

<xsl:template match="root/date2/text()">
      <xsl:variable name="c1" select="greg:getInstance()" />
      <xsl:variable name="d1" select="sql:valueOf(.)" />
      <xsl:value-of select="greg:setTime($c1,$d1)" />
      <xsl:value-of select="greg:getTime($c1)" />
</xsl:template>

</xsl:transform>

结果:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<date1>2010-04-14T08:23:25.341Z</date1>
<date2>2009-01-01T23:00:00Z</date2>
</root>

所以似乎setTime()不是 date1 调用的,而是 date2 调用的。

Saxon 有一个很好的explain功能,可以以可读的格式显示解析后的转换:

...
<templateRule match="root/date2/text()" precedence="0" priority="0.5" line="21"
              module="file:/C:/devtools/saxonb9-0-0-8j/template.xsl">
  <let variable="c1" as="java:java.util.Calendar?">
    <be>
      <functionCall name="greg:getInstance"/>
    </be>
    <return>
      <sequence>
        <valueOf>
          <simpleContentConstructor>
            <functionCall name="greg:setTime">
              <variableReference name="c1"/>
              <functionCall name="sql:valueOf">
                <dot/>
              </functionCall>
            </functionCall>
            <literal value=" " type="xs:string"/>
          </simpleContentConstructor>
        </valueOf>
        <valueOf>
          <simpleContentConstructor>
            <functionCall name="greg:getTime">
              <variableReference name="c1"/>
            </functionCall>
            <literal value=" " type="xs:string"/>
          </simpleContentConstructor>
        </valueOf>
      </sequence>
    </return>
  </let>
</templateRule>
<templateRule match="root/date1/text()" precedence="0" priority="0.5" line="14"
              module="file:/C:/devtools/saxonb9-0-0-8j/template.xsl">
  <valueOf>
    <simpleContentConstructor>
      <functionCall name="greg:getTime">
        <functionCall name="greg:getInstance"/>
      </functionCall>
      <literal value=" " type="xs:string"/>
    </simpleContentConstructor>
  </valueOf>
</templateRule>
...

如您所见,对于 date1,调用setTime()被忽略,但 date2 存在。

于 2010-04-14T08:30:10.607 回答
0

您是否使用 java.sql.Date 作为参数在 GregorianCalendar 上调用 setTime?那不应该失败吗?还是发生了一些隐藏的转变?

如果它失败了,也许撒克逊人会默默地忽略错误?

我注意到在某些版本的 Xalan 中,对 void 函数的调用会被 XSLT 编译器忽略。撒克逊人的行为可能类似。

于 2010-04-13T16:58:26.270 回答