2015-05-03 3 views
4

Я пытаюсь форматировать дату в XSLT 2.0. Когда я пытаюсь запустить его в своем рабочем пространстве, он работает нормально, и я получаю правильный ответ. Но когда я пытаюсь достичь таких же после развертывания моей баночки на JBoss еара 6.1 я получаю ниже ошибок:Как включить процессор XSLT 2.0 на сервере JBoss eap 6.1, чтобы избавиться от ошибок, например, функции XSLT 2.0 недоступны

16. 35: 02311 ERROR [XSLTUtil] (DefaultQuartzScheduler-верблюд-12_Worker-2) XSLTUtil | 0 | TransformerException: Ошибка при преобразовании xml с файлом xslt: javax.xml.transform.TransformerException: org.xml.sax.SAXException: не удалось найти функцию: format-dateTime javax.xml.transform.TransformerException: не удалось найти функцию : format-dateTime |

Мой файл Xsl: здесь я пытаюсь отформатировать текущую дату в другом формате с использованием format-dateTime.

<?xml version='1.0' encoding='UTF-8'?> 
<xsl:stylesheet version='2.0' 
    xmlns:xsl='http://www.w3.org/1999/XSL/Transform' 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:func="http://exslt.org/functions" 
    xmlns:date="http://exslt.org/dates-and-times" 
    date:doc="http://www.exslt.org/date" exclude-result-prefixes="date func"> 

    <xsl:import href="date.xsl"/> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 
    <xsl:template match="/"> 
     <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:max="http://www.ibm.com/maximo"> 
      <soapenv:Header/> 
      <soapenv:Body> 
       <max:CreateMXINCIDENT_WSTB creationDateTime="" baseLanguage="" transLanguage="" messageID="" maximoVersion=""> 
        <max:MXINCIDENT_WSTBSet> 
         <max:MXINCIDENT_WST action="" relationship="" deleteForInsert="" transLanguage=""> 
          <max:MAXINTERRORMSG></max:MAXINTERRORMSG> 
          <max:ACTIVITY changed="true"> 
           <xsl:value-of select='/tTroubleticket/activity' /> 
          </max:ACTIVITY> 
          <max:BLOCK changed=""> 
           <xsl:value-of select='/tTroubleticket/block' /> 
          </max:BLOCK> 
          <max:CHANGEBY changed="true">AOS</max:CHANGEBY> 
          <max:CHANGEDATE changed="true"> 
           <xsl:value-of select="format-dateTime(current-dateTime(), '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f001][Z]')" /> 
          </max:CHANGEDATE> 
          <max:CLASS changed="true">INCIDENT</max:CLASS> 
          <max:COMMERRORTYPE changed="true"> 
           <xsl:value-of select='/tTroubleticket/commErrorType' /> 
          </max:COMMERRORTYPE> 
          <max:COMPONENTLIST changed="true"></max:COMPONENTLIST> 
          <max:CREATEDBY changed=""></max:CREATEDBY> 
          <max:CREATIONDATE changed="true"> 
           <xsl:value-of select="/tTroubleticket/interactiondate" /> 
           <!-- <xsl:variable name="date" select="/tTroubleticket/interactiondate"></xsl:variable> 
           <xsl:variable name="intDt" select="xs:dateTime(concat(
            substring($date, 1, 4),'-', 
            substring($date, 6, 2),'-', 
            substring($date, 9, 2),'T', 
            substring($date, 12, 2),':', 
            substring($date, 15, 2),':', 
            substring($date, 18, 2)))"></xsl:variable> 
           <xsl:value-of select="format-dateTime($intDt, '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f001][Z]')" /> --> 
          </max:CREATIONDATE> 
          <max:DESCRIPTION changed=""> 
           <xsl:variable name="objOwner" select="/tTroubleticket/mc_object_owner" /> 
           <xsl:variable name="mcOwner" select="/tTroubleticket/mc_owner" /> 
           <xsl:value-of select="concat($objOwner,'|',$mcOwner)" /> 
          </max:DESCRIPTION> 
          </max:MXINCIDENT_WST> 
        </max:MXINCIDENT_WSTBSet> 
       </max:CreateMXINCIDENT_WSTB> 
      </soapenv:Body> 
     </soapenv:Envelope> 
    </xsl:template> 
</xsl:stylesheet> 

Вот XSLT класс Util, который я использую для преобразования/отображений моего XML и XSL файлов. В нижнем java-файле я читаю xsl-файл из своего локального каталога. Как только я развожу свою банку на сервер JBoss, я прохожу считываю местоположение файла и передаю его переменной XSLTFilename.

package com.al.ddr.fsw.tt.util.xml.transform; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.StringReader; 
import java.io.StringWriter; 
import com.al.ddr.common.logging.jb.Logger;  
import javax.xml.transform.Source; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.TransformerFactoryConfigurationError; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.transform.stream.StreamSource; 

public class XSLTUtil { 

    Logger logger = Logger.getLogger(XSLTUtil.class); 
    //Logger logger = Logger.getLogger("XSLTUtil"); 

    public String transformXML(String inXML, String XSLTFilename) throws TransformerFactoryConfigurationError, TransformerException { 
     StringWriter xmlResultResource = new StringWriter(); 
     try { 
      Source xslDoc = new StreamSource(XSLTFilename); 
      Transformer transformer = TransformerFactory.newInstance().newTransformer(xslDoc); 
      transformer.transform(new StreamSource(new StringReader(inXML)), new StreamResult(xmlResultResource)); 
      //logger.info("XSLTUtil",0,"XSLTUtil - transformXML() - Result : \n" + xmlResultResource.getBuffer().toString(),""); 
     } catch (TransformerException e) { 
      //logger.error("XSLTUtil",0,"TransformerException : Error occured while transforming xml with the xslt file : \n"+e.getMessage(),""); 
     } catch (Exception e) { 
      e.getMessage(); 
      //logger.error("XSLTUtil",0,"Error occured while transforming xml with the xslt file : \n"+e.getMessage(),""); 
     } 
     return xmlResultResource.getBuffer().toString(); 
    } 

    public static void main(String[] args) throws TransformerFactoryConfigurationError, TransformerException { 

     String xmlSourceResource = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + "<tTroubleticket>" + "<alarms>" + "<tTroubleTicketAlarm>" + "<alarmid>3117</alarmid>" 
       + "<alarmName>OSS</alarmName>" + "</tTroubleTicketAlarm>" + "<tTroubleTicketAlarm>" + "<alarmid>3118</alarmid>" + "<alarmName>OS123</alarmName>" + "</tTroubleTicketAlarm>" 
       + "</alarms>" + "<interactiondate>2014-11-21 11:22:34</interactiondate>" + "<troubleticketstate>QUEUED</troubleticketstate>" 
       + "<mc_object_owner>amit</mc_object_owner>"+ "<mc_owner>kumar</mc_owner>" 
       + "<troubledescription>Server down</troubledescription>" + "<system>IRU</system>" + "<subsystem>FJKH</subsystem>" + "<severity>1</severity>" + "<tecGroup>NSN</tecGroup>" 
       + "<block>block</block>" + "<subBlock>sub_block</subBlock>" + "<history>new ticket created</history>" + "<Log>" + "<Logname>FJKH</Logname>" + "<LogSize>Nothing</LogSize>" 
       + "<LogFile>" + "Hi" + "</LogFile>" + "</Log>" + "</tTroubleticket>"; 

     String xsltFilename = "C:/Users/akuma249/TTSimulator/aor-platform-tt/src/config/xslt_COLOMBIA/v11/CreateTicketRequest_WS_11.xsl"; 

     XSLTUtil util = new XSLTUtil(); 
     String transformedXML = util.transformXML(xmlSourceResource, xsltFilename); 
     System.out.println(transformedXML); 

    } 

} 

Этот конкретный фрагмент кода отлично работает в моем рабочем пространстве. Нужно ли мне что-то настраивать на моем сервере JBoss, чтобы исправить эту проблему? Пожалуйста, дайте мне знать, что именно мне не хватает.

+1

«* I Я пытаюсь форматировать дату в XSLT с помощью EXSLT. * «Нет, не совсем. Вы просто объявили два пространства имен EXSLT, но вы их вообще не используете. Вместо этого вы используете две функции ** XSLT 2.0 ** ('format-dateTime()' и 'current-dateTime()'), которые, по-видимому, ваш процессор не поддерживает. Также обратите внимание, что не все процессоры XSLT 1.0 поддерживают все функции расширения EXSLT; 'date: format-date()' в частности не поддерживается никаким процессором, о котором я знаю. –

+0

Вы пишете, я не использую никаких функций EXSLT. Моя фактическая проблема заключалась в том, как включить процессор XSLT 2.0 на моем сервере JBoss eap 6.1. Который я смог выяснить, переопределив javax.xml.transform.TransformerFactory с помощью SAXON (net.sf.saxon.TransformerFactoryImpl). – dev

+0

@ amit4497 Связаться с Red hat support !! –

ответ

4

Для того, чтобы переопределить Xalan процессор, который по умолчанию поддерживается в JBoss EAP 6.1 мы можем добавить JAVA_OPTS = "$ JAVA_OPTS -Djavax.xml.transform.TransformerFactory = net.sf.saxon.TransformerFactoryImpl" в standalone.conf Это переопределяет процессор XALAN, который поддерживает XSLT 1.0 и SAXON, который поддерживает XSLT 2.0. Спасибо @Martin Honnen за подсказку.

0

Линия <xsl:value-of select="format-dateTime(current-dateTime(), '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f001][Z]')" /> вместе с линиями <xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xs="http://www.w3.org/2001/XMLSchema" предлагает вам использовать тип данных XSLT 2.0 dateTime. Для этой работы вам необходимо использовать XSLT 2.0-процессор, такой как Saxon 9. Если у вас возникла ошибка в том, что такие функции не определены, вы, вероятно, используете код с процессором XSLT 1.0, например Xalan. Я не знаком с jboss, поэтому не могу сказать, как настроить его для использования процессора XSLT 2.0 вместо процессора XSLT 1.0.

+0

Сообщение без какого-либо решения имеет место только как комментарий – berhauz

1

Установка опции флаг Java

-Djavax.xml.transform.TransformerFactory=net.sf.saxon.TransformerFactoryImpl

в вашем App запуска сервера скрипт делает также требовать простой виртуальной машины Java, чтобы получить доступ к, например, как saxon-8.7.jar, так и saxon-dom-8.7.jar на пути к классу.

Но при этом, все ваши шаблоны XSL потребует < XSL: таблицы стилей версия = «2,0» ... > иначе вы получите «Предупреждение: Запуск XSLT 1.0 таблицы стилей с XSLT 2.0 процессор» и действительно ожидается possible changes in behavior.

Кроме того, добавление таких глобальных библиотек классов к JVM-серверу выполняется против философии последних версий сервера, таких как WildFly 10/JBoss EAP7, где предпочтительными являются модули расширения.

Если - как в моем JBoss EAP7 контексте - вы предпочитаете избежать регрессивного тестирования сотен шаблонов XSLT 1.0 и выгоду от 2,0 функций, просто create a new module для размещения саксонских библиотек, add it to the list of global modules вашей подсистемы EE, предполагая, что на самом деле, что вы выполняете ваши преобразования в EJB; в этом случае артефактам развертывания нужны саксонские библиотеки в качестве зависимостей, но применяется область Maven. Кроме того, вы можете захотеть развернуть саксонные банки рядом с вашей WAR или EAR (компиляция Maven Scope) и забыть о глобальных модулях.

В любом случае, когда вы хотите, чтобы извлечь выгоду из особенностей XSLT2.0, просто замените:

javax.xml.transform.TransformerFactory tf = javax.xml.transform.TransformerFactory.newInstance(); 

по

javax.xml.transform.TransformerFactory tf = net.sf.saxon.TransformerFactoryImpl.newInstance(); 

Остальной ваш код не тождественны.

Для усиления назад преобразование XSLT 1.0, а затем использовать (проверьте путь Xalan пакет для завода Impl, который изменяется в зависимости от варианта версии и заводских марок)

javax.xml.transform.TransformerFactory tf = org.apache.xalan.processor.TransformerFactoryImpl.newInstance(); 

или

javax.xml.transform.TransformerFactory tf = javax.xml.transform.TransformerFactory.newInstance(
        "org.apache.xalan.processor.TransformerFactoryImpl", 
        ClassLoader.getSystemClassLoader()); 
+0

Остановимся на двух проблемах: (a) наличие саксонских библиотек в вашем CLASSPATH, иначе в развертывании WAR или EAR, изменяет заводскую фабрику трансформаторов по умолчанию на Saxon (автоматически регистрируя себя как новый поставщик по умолчанию). Поэтому для обеспечения преобразования XSLT 1.0 вы должны явно ссылаться на него, например. тс = javax.xml.transform.TransformerFactory.newInstance ( \t \t \t \t "org.apache.xalan.processor.TransformerFactoryImpl", \t \t \t \t ClassLoader.getSystemClassLoader()); (b) Я отметил побочные эффекты Saxon на поведение DOM API, особенно связанную с setNamespaceAware() – berhauz

Смежные вопросы