Как выполнить XSLT 2.0 с муравьем? - PullRequest
8 голосов
/ 28 мая 2009

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

19 голосов
/ 31 мая 2009

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

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

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

3 голосов
/ 28 мая 2009

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

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

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

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

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

1 голос
/ 13 декабря 2010

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

1 голос
/ 30 августа 2009

РЕДАКТИРОВАТЬ: Dr. Майкл Кей указал, что 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> с саксонским 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>  
0 голосов
/ 02 апреля 2011

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

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

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

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

...