【问题标题】:Using Saxon alongside Xalan将 Saxon 与 Xalan 一起使用
【发布时间】:2018-09-06 07:21:06
【问题描述】:

我有一个使用 Xalan 作为 XSLT 处理器的应用程序。我现在想使用撒克逊语。我想确保所有现有的转换仍然有效。因此,我想对所有现有的 XML 文件使用 Xalan。对于新的 XML 文件,我想使用 Saxon。 总而言之,我想同时使用这两个处理器。 因此我像这样实例化处理器:

TransformerFactory.newInstance("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl", null);
or
TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", null);

在我现有的所有单元测试中,我都使用 Xalan。但是当我将 Saxon 添加到我的类路径时,其中一些失败了。失败的测试都使用 Apache FOP 创建 PDF 文件。不同之处在于,现在在生成的 PDF 中插入了一些选项卡(缩进键)(不在可见内容中,我只是在比较字节码时看到它们)。 我认为这种行为很奇怪,因为我仍然使用 Xalan 并期望得到与我的类路径中没有 Saxon 时相同的结果。 那么当 Saxon 在类路径中时还有什么变化呢?

当我添加时

System.setProperty("javax.xml.transform.TransformerFactory",
            "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");

在我的测试中,它再次与类路径中的 Saxon 一起使用。但这不是我生产环境的解决方案,因为我想在两个处理器之间动态切换。

那么当我将 Saxon 添加到我的类路径时,有人知道还有什么变化吗? 非常感谢!

更新: 我设置了 jaxp.debug 标志并获得以下输出(在类路径中使用 Xalan 和 Saxon)

    JAXP: created new instance of class org.apache.xalan.xsltc.trax.TransformerFactoryImpl using ClassLoader: null
JAXP: created new instance of class org.apache.xalan.xsltc.trax.TransformerFactoryImpl using ClassLoader: null
JAXP: created new instance of class org.apache.xalan.xsltc.trax.TransformerFactoryImpl using ClassLoader: null
Calling com.saxonica.SchemaFactoryImpl.isSchemaLanguageSupported("http://www.w3.org/2001/XMLSchema"); returning true
JAXP: created new instance of class org.apache.xalan.xsltc.trax.TransformerFactoryImpl using ClassLoader: null
JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: created new instance of class org.apache.xalan.xsltc.trax.TransformerFactoryImpl using ClassLoader: null

当我从类路径中删除 saxon 时,我得到以下输出:

JAXP: created new instance of class org.apache.xalan.xsltc.trax.TransformerFactoryImpl using ClassLoader: null
JAXP: created new instance of class org.apache.xalan.xsltc.trax.TransformerFactoryImpl using ClassLoader: null
JAXP: created new instance of class org.apache.xalan.xsltc.trax.TransformerFactoryImpl using ClassLoader: null
JAXP: created new instance of class org.apache.xalan.xsltc.trax.TransformerFactoryImpl using ClassLoader: null
JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: created new instance of class org.apache.xalan.xsltc.trax.TransformerFactoryImpl using ClassLoader: null

所以我真的使用 Xalan 处理器。输出的不同之处在于类路径中没有撒克逊人我看不到这条线

Calling com.saxonica.SchemaFactoryImpl.isSchemaLanguageSupported("http://www.w3.org/2001/XMLSchema"); returning true

阅读此question 后,我添加了建议的行以获取有关所有工厂的信息。当我使用 xalan 处理器(在类路径中使用 saxon)时,我得到了

DocumentBuilderFactory implementation: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl loaded from: Java Runtime
    XPathFactory implementation: org.apache.xpath.jaxp.XPathFactoryImpl loaded from: file:/D:/repository/xalan/xalan/2.7.1/xalan-2.7.1.jar
    TransformerFactory implementation: com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl loaded from: Java Runtime
    SAXParserFactory implementation: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl loaded from: Java Runtime

当我使用 Saxon 时,我得到了

    DocumentBuilderFactory implementation: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl loaded from: Java Runtime
XPathFactory implementation: org.apache.xpath.jaxp.XPathFactoryImpl loaded from: file:/D:/repository/xalan/xalan/2.7.1/xalan-2.7.1.jar
TransformerFactory implementation: com.saxonica.config.EnterpriseTransformerFactory loaded from: file:/D:/repository/de/soptim/contrib/net/sf/saxon/Saxon-EE/9.8.0.14/Saxon-EE-9.8.0.14.jar
SAXParserFactory implementation: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl loaded from: Java Runtime

【问题讨论】:

    标签: java xslt xsl-fo saxon xalan


    【解决方案1】:

    我认为您必须进行一些使用TransformerFactory.newInstance() 而不指定处理器的转换。尝试设置 jaxp.debug 系统属性以获取有关加载过程的诊断信息。

    我建议设置系统属性

    System.setProperty("javax.xml.transform.TransformerFactory",
                "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
    

    因此默认情况下会调用 Xalan,并使用

    TransformerFactory saxon = new net.sf.saxon.TransformerFactoryImpl();
    

    在您想要调用 Saxon 的情况下。如果你想动态地做出决定,那么在你自己的代码中使用一些条件逻辑来控制它。

    【讨论】:

    • 感谢您的回答。我使用了 jaxp.debug 标志并将输出添加到我的问题中。我看到的是,在类路径中使用 saxon,我从 saxonica 获得了有关 SchemaFactory 的信息。也许这会有所作为。
    • 但是当你作为 saxon 的开发者告诉我我可以将系统属性设置为 xalan 并且只使用 saxon 作为transformerFactory 时,我会这样做。我只是害怕撒克逊还需要其他一些东西,比如 XPathFactory 才能运行没有任何问题。
    • SchemaFactory 行当然很有趣。您需要找出应用程序的哪一部分正在实例化 SchemaFactory 以及为什么,以及一旦获得了模式工厂,它将如何处理它。我看不出这将如何解释您最终 PDF 输出的差异,但这肯定是需要调查的线索。
    猜你喜欢
    • 2012-06-28
    • 2016-08-21
    • 2013-05-03
    • 2014-03-30
    • 2021-03-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多