2010-04-13 7 views
0

Я работаю с версией Saxon XSLT с открытым исходным кодом Saxon 9.0.0.2J от Saxonica и пытаюсь использовать Java-расширяемость в первый раз. Я запускаю в проблеме, которая, как я подозреваю, может быть ограничением в версии с открытым исходным кодом, но сначала захотела проверить, может ли быть что-то, что я здесь просто отсутствует.Не удается получить доступ к обновленному объекту Java от Saxon XSLT-процессора

Из нижеприведенного фрагмента моего результата получается, что конечное значение $ c1 не изменяется в результате вызова greg: setTime() - то есть переменная $ c1 в Saxon, по-видимому, отцепляется от базовой 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> 
+0

Можете ли вы предоставить короткий автономный пример файла ввода XML и файла преобразования XSL? –

+0

Нашел пример сам. См. Мой ответ. –

ответ

1

Я только что попробовал с saxonb9-0-0-8j.

Звонки на недействительные функции иногда игнорируются, о чем свидетельствует следующее.

Входной файл:

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

+0

Ох, христианин, тебе это понравится. Некоторое время я царапал себе голову, прежде чем осознать, что вы нашли решение через надзор над пропиткой.Обратите внимание, что ваш шаблон для date2 вызывает setTime через , в то время как шаблон для даты1 вызывает через , как в моем исходном фрагменте. Ваш измененный шаблон date2 приведет к успешному вызову. Я переместил эту логику в мое преобразование, и теперь все работает. Большое спасибо за вашу вторую пару глаз и вашу ошибку «n paste»! –

+0

Извините, что вы не понимаете разницу. :-) Я играл разными способами, чтобы вызвать функцию Java, и работал вариант date2. Но я не знаю почему. –

0

Вы вызываете setTime на GregorianCalendar с помощью java.sql.Date в качестве аргумента? Разве это не так? Или есть какое-то скрытое преобразование?

Если это не удается, возможно, саксон молча игнорирует ошибку?

Я заметил, что в некоторых версиях Xalan вызовы функций void игнорируются компилятором XSLT. Саксон может вести себя аналогично.

+0

Спасибо, христианин. Я не верю, что это должно завершиться неудачно - java.sql.Date является прямым подклассом java.util.Date. Кроме того, любой вызов для установки отдельного поля в объекте календаря дает тот же не обновленный результат для $ c1, поэтому я думаю, что мы имеем дело с проблемой более высокого уровня того, как экземпляры объектов/переменных связаны между Java и Saxon. –

+0

Я никогда не использовал java.sql.Date напрямую, поэтому я никогда не замечал, что это подкласс. :-) Вы правы тогда: тип аргумента не является причиной. –