Cannot access updated Java object from Saxon XSLT processor

筅森魡賤 提交于 2019-12-12 10:19:46

问题


I am working with an open source version of the Saxon XSLT processor "Saxon 9.0.0.2J from Saxonica" and am trying to make use of the java extensibility for the first time. I am running into an issue I suspect may be a limitation on the open source version, but wanted to check first whether there might be something I am just missing here.

From the snippet below, my result is that the final value of $c1 does not change as a result of the call to greg:setTime() - i.e. the $c1 variable within Saxon appears to be unhooked from the underlying Java object and there is no apparent way to access the object as updated by the setTime() call.

NOTE that all code in the snippet is tested and working otherwise - i.e. $c1 is properly instantiated by the getInstance() call, $startdate is of the proper format and $d1 is properly instantiated.

Thoughts?

<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>

回答1:


I just tried with saxonb9-0-0-8j.

Calls to void functions are sometimes ignored, as demonstrated by the following.

The input file:

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

The transform:

 <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>

The result:

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

So it seems that setTime() is not called for date1, but for date2.

Saxon has a nice explain feature that displayes the parsed transformation in a readable format:

...
<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>
...

As you see, for date1, the call to setTime() is ignored, but is there for date2.




回答2:


Are you calling setTime on a GregorianCalendar with a java.sql.Date as argument? Shouldn't that fail? Or is there some hidden conversion taking place?

If it fails, maybe Saxon silently ignores the error?

I noticed that in some versions of Xalan, calls to void functions are ignored by the XSLT compiler. Saxon may behave similar.



来源:https://stackoverflow.com/questions/2631301/cannot-access-updated-java-object-from-saxon-xslt-processor

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