10

我正在尝试从ant文件运行 XSLT 转换。

我正在使用带有saxon 9解析器(支持 XSLT 2.0)的 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>

如果我直接调用它(没有蚂蚁),它就可以工作。

任何的想法 ?

4

6 回答 6

20

问题是当 Saxon 添加到类路径时,默认的 JAXP 机制来确定使用哪个 TransformerFactory,它将使用默认的 Xalan。您要么需要:

  • javax.xml.transform.TransformerFactory系统变量设置为net.sf.saxon.TransformerFactoryImpl,
  • 将 saxon9.jar 添加到CLASSPATH系统变量中,或
  • <factory name="net.sf.saxon.TransformerFactoryImpl"/>xslt元素内部使用
于 2009-05-31T13:53:37.303 回答
7

如果您遇到此问题,请检查您使用的不是 Ant 1.8.1,因为 Ant 1.8.1 中有一个错误会阻止此操作。(虽然这不是原始帖子中的问题,因为那是在 Ant 1.8.1 发布之前)。

您的选择是:

  1. 使用没有错误的 Ant 版本(例如 Ant 1.7.1)。
  2. CLASSPATH在Ant 启动之前,在 saxon9.jar 中显式指定它,方法是:
    • 设置系统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 年 6 月创建以来一直没有更新)。

从理论上讲,指定factory子元素会使您要使用的 XSLT 处理器显式化——以防止类加载器在其搜索的早期找到不同的 XSLT 处理器,并使用它来代替在 CLASSPATH 中更靠后的 XSLT 处理器。在实践中(至少在 ant 1.7.0、1.7.1 和 1.8.0 中),如果factory指定了子元素,则xslt任务会忽略该classpath属性——这意味着您必须求助于显式指定 CLASSPATH(选项 2)。所以它无助于解决原来的问题。但是,这似乎已在 Ant 源代码中修复,因此可以在 1.8.1 之后的版本中使用。

于 2010-11-18T04:00:47.107 回答
3

本教程似乎提供了有关如何执行您所要求的操作的分步说明:

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

由此看来,您正在做正确的事情。你确定你需要双反斜杠吗?

更新:xslt Ant 文档提到了可以帮助您更接近的“工厂”属性:

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

于 2009-05-28T09:02:53.797 回答
2

编辑: Michael Kay 博士指出 AntTransform 不再受支持,也不推荐。

从 Saxon AntTransform 类创建一个 taskdef :

  <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>带有 a 中指定的 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>  
于 2009-08-30T01:34:53.487 回答
1

无需等待在 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>

您可以在http://www.saxonica.com/documentation/using-xsl/commandline.xml找到将参数传递给 Saxon 的文档

于 2010-12-13T20:27:46.243 回答
0

至少在 ant 1.8.0 中,指定类路径的 xslt 任务非常慢。问题似乎是类路径加载。我在 JDB 下运行 ant,它把所有额外的时间都花在了 org.apache.tools.ant.AntClassLoader.loadClass 读取 zip 文件上。

我在运行 ant 之前尝试过它,它运行得更快:

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

来自 Tom Howard 的 macrodef 效果更好,虽然它对 XSLT 参数有一种奇怪的语法,但至少它是可能的。

于 2011-04-01T23:09:41.017 回答