与Xalan一起使用Saxon

时间:2018-09-06 07:21:06

标签: java xslt xsl-fo saxon xalan

我有一个使用Xalan作为XSLT处理器的应用程序。我现在想使用Saxon。我想确保所有现有的转换仍然有效。因此,我想对所有现有的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

当我使用撒克逊时,我得到了

    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

1 个答案:

答案 0 :(得分:1)

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

我建议设置系统属性

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

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

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

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