Как выполнить XSLT 2.0 с муравьем?

Я пытаюсь запустить 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>

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

Любая идея?

6 ответов

Решение

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

  • Задавать javax.xml.transform.TransformerFactory системная переменная net.sf.saxon.TransformerFactoryImpl,
  • Добавьте saxon9.jar к CLASSPATH системная переменная, или
  • использование <factory name="net.sf.saxon.TransformerFactoryImpl"/> внутри xslt элемент

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

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

  1. Используйте версию Ant, в которой нет ошибки (например, Ant 1.7.1).
  2. Явно укажите saxon9.jar в CLASSPATH Ant до его запуска, либо:
    • Настройка системы CLASSPATH переменная среды, или
    • Использовать -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. На практике (по крайней мере, в муравье 1.7.0, 1.7.1 и 1.8.0), если factory субэлемент указан xslt задача игнорирует classpath Атрибут - это означает, что вы должны явно указать CLASSPATH (вариант 2). Так что это не поможет решить исходную проблему. Однако это, похоже, исправлено в исходном коде Ant, поэтому может работать в выпусках после 1.8.1.

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

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

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

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

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

РЕДАКТИРОВАТЬ: Michael Kay отметил, что AntTransform больше не поддерживается и не рекомендуется.

Создайте taskdef из класса 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> задание с саксонской флягой, указанной в <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>  

Вместо того, чтобы ждать, пока это будет исправлено в 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

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

Я пробовал это перед запуском и пошло намного быстрее:

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

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

Другие вопросы по тегам