Как выполнить XSLT 2.0 с помощью ant?

Я пытаюсь запустить преобразование XSLT из файла ant.

Я использую таблицу стилей XSLT 2.0 с парсером saxon 9 (поддерживающим XSLT 2.0).

Проблема в том, что ant всегда вызывает синтаксический анализатор XSLT 1.0.

Вот мой муравьиный файл:

<xslt style="stylesheet.xslt"
   basedir="core/"    
   extension=".xml"
   destdir="core/"
   classpath="D:\\DevTools\\saxon\\bin\\saxon9.jar">
</xslt>

Если я вызову его напрямую (без муравья), он сработает.

Любая идея ?


person paulgreg    schedule 28.05.2009    source источник
comment
Это может быть интересно xml.com/pub/a/ 2002/12/11/ant-xml.html, но немного устарел (последнее обновление mtxslt — 2002 г. — mtxslt .sf.net)   -  person paulgreg    schedule 28.05.2009


Ответы (6)


Проблема в том, что хотя Saxon добавляется в путь к классам, механизм JAXP по умолчанию для определения того, какой TransformerFactory используется, и он будет использовать по умолчанию Xalan. Вам либо необходимо:

  • Установите для системной переменной javax.xml.transform.TransformerFactory значение net.sf.saxon.TransformerFactoryImpl,
  • Добавьте saxon9.jar в системную переменную CLASSPATH или
  • Используйте <factory name="net.sf.saxon.TransformerFactoryImpl"/> внутри элемента xslt
person jelovirt    schedule 31.05.2009

Если у вас возникла эта проблема, убедитесь, что вы не используете Ant 1.8.1, так как существует ошибка в Ant 1.8.1, из-за которой это не работает. (Хотя это не проблема в исходном посте, потому что это было до выпуска Ant 1.8.1).

Ваши варианты:

  1. Используйте версию Ant, в которой нет ошибки (например, Ant 1.7.1).
  2. Explicitly specify saxon9.jar in the CLASSPATH to Ant before it starts, by either:
    • Setting the system CLASSPATH environment variable, or
    • Используйте параметр командной строки -lib для ant
  3. Определите свою собственную задачу, используя SAXON Ant (как описано в другом ответе в этой теме).
  4. Обходной путь путем добавления processor="org.apache.tools.ant.taskdefs.optional.TraXLiaison" в качестве атрибута элемента задачи xslt.

Я бы предложил использовать вариант 1, а затем вариант 4.

Вариант 2 будет работать, но он возлагает на человека, управляющего ant, ответственность за настройку своей среды и правильный запуск ant. Я предполагаю, что вы этого не хотите, поэтому вы пытаетесь заставить работать атрибут classpath в задаче xslt.

Вариант 3 имеет ограничения, так как SAXON Ant требует загрузки и установки JAR-файла. Также SAXON Ant не работает с SAXON 9.2 или более поздней версии (и SAXON Ant не обновлялся с момента его создания в июне 2008 года).

Теоретически, указание подэлемента factory делает XSLT-процессор, который вы хотите использовать, явным, чтобы предотвратить обнаружение загрузчиком классов другого XSLT-процессора ранее в его поиске и использование его вместо вашего XSLT-процессора, который находится ниже в CLASSPATH. . На практике (по крайней мере, в ant 1.7.0, 1.7.1 и 1.8.0), если указан подэлемент factory, задача xslt игнорирует атрибут classpath, что означает, что вы должны прибегнуть к явному указанию CLASSPATH (вариант 2). Так что это не помогает решить исходную проблему. Однако это, кажется, было исправлено в исходном коде Ant, поэтому может работать в выпусках после 1.8.1.

person Hoylen    schedule 18.11.2010
comment
вот ссылка на ошибку задачи ant 1.8.1 xslt: issues.apache. org/bugzilla/show_bug.cgi?id=49271 - person Kai Sternad; 30.11.2010

Этот учебник, кажется, дает пошаговые инструкции о том, как делать то, что вы просите:

http://www.abbeyworkshop.com/howto/xslt/ant-saxon/index.html

Отсюда видно, что вы поступаете правильно. Вы уверены, что вам нужна двойная косая черта?

Обновление: в документации xslt Ant упоминается свойство factory, которое может помочь вам приблизиться:

http://ant.apache.org/manual/Tasks/style.html

person samjudson    schedule 28.05.2009

Вместо того, чтобы ждать, пока это будет исправлено в 1.8.2, а затем ждать, пока все в конечном итоге обновятся до 1.8.2, вы можете создать свой собственный макрос XSLT (для ситуаций, когда вы явно хотите использовать Saxon, а не выбранный пользователем механизм XSLT). )

<macrodef name="xslt" uri="com.mycompany.mydepartment">
    <attribute name="in" />
    <attribute name="out" />
    <attribute name="style" />
    <attribute name="classpath" default="${saxon.jar.path}" />
    <attribute name="taskname" default="mydep:xslt" />
    <element name="params" optional="true" implicit="true" />
    <sequential>
        <java classname="net.sf.saxon.Transform"
              classpath="@{classpath}"
              taskname="@{taskname}">
            <classpath path="${saxon.jar.path}" />
            <arg value="-s:@{in}" />
            <arg value="-xsl:@{style}" />
            <arg value="-o:@{out}" />
            <params />
        </java>
    </sequential>
</macrodef>

затем вы можете вызвать его как (при условии, что xmlns:mydep="com.mycompany.mydepartment" установлен в элементе проекта)

<mydep:xslt in="${myinput}"
             out="${myoutput}"
             style="${myxslt}">
    <arg value="param1=value1" />
    <arg value="param2=value2" />
    <arg value="+param3=somefile.xml" />
</mydep:xslt>

Вы можете найти документацию по передаче параметров в Saxon по адресу http://www.saxonica.com/documentation/using-xsl/commandline.xml

person Tom Howard    schedule 13.12.2010

EDIT: Dr. Майкл Кей указал, что AntTransform больше не поддерживается и не рекомендуется.

Создайте определение задачи из Saxon класса AntTransform< /а>:

  <taskdef name="saxon-xslt" classname="net.sf.saxon.ant.AntTransform" classpath="${basedir}/lib/saxon/saxon9.jar;${basedir}/lib/saxon/saxon9-ant.jar"/>

   <saxon-xslt
     in="${source.xml}"
     out="${out.dir}/${output.xml}"
     style="${basedir}/${stylesheet.xsl}"
     force="true">
   </saxon-xslt>


Я начал использовать стандартную задачу <xslt> с saxon jar, указанным в <classpath>, но столкнулся с проблемами производительности. Казалось, что он немного «завис» при вызове задачи. Я обнаружил, что добавление processor="trax" и указание <factory name="net.sf.saxon.TransformerFactoryImpl"/> помогает ему работать намного быстрее.

 <xslt in="${source.xml}"
       out="${out.dir}/${output.xml}"
       style="${basedir}/${stylesheet.xsl}"
       processor="trax">
       <factory name="net.sf.saxon.TransformerFactoryImpl"/>
       <classpath refid="saxon-classpath" />
 </xslt>  
person Mads Hansen    schedule 30.08.2009
comment
Обратите внимание, что задача AntTransform больше не рекомендуется. Он оказался ошибочным, и не было реальной стратегии для его надлежащего тестирования, поскольку Apache не выпускает комплексный набор тестов для Ant. - person Michael Kay; 14.01.2011
comment
Отмеченный. Я начал использовать стандартную задачу <xslt> с saxon jar, указанным в <classpath>, но столкнулся с проблемами производительности. Казалось, что это немного зависло, когда задача была вызвана. Недавно я обнаружил, что добавление processor="trax" и указание <factory name="net.sf.saxon.TransformerFactoryImpl"/> помогает ему работать намного быстрее. - person Mads Hansen; 14.01.2011

По крайней мере, в ant 1.8.0 задача xslt с указанным путем к классам выполняется очень медленно. Проблема, похоже, в загрузке пути к классам. Я запускал ant под JDB, и все дополнительное время он проводил в org.apache.tools.ant.AntClassLoader.loadClass, читая zip-файлы.

Я попробовал это, прежде чем запускать муравей, это пошло намного быстрее:

ant -lib /path/to/saxon/saxon9.jar

Макрос от Tom Howard работает лучше, и хотя у него странный синтаксис для XSLT-параметров, по крайней мере, это возможно.

person Leigh Klotz    schedule 01.04.2011