Использование саксонской вместе с Xalan - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть приложение, в котором я использую Xalan в качестве процессора XSLT. Теперь я хочу использовать саксонский. Я хочу быть уверен, что все существующие преобразования все еще работают. Поэтому я хочу использовать Xalan для всех существующих XML-файлов. Для новых XML-файлов я хочу использовать Saxon. Подводя итог, я хочу использовать оба процессора вместе. Поэтому я создаю экземпляр процессора следующим образом:

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

Во всех моих существующих модульных тестах я использую Xalan. Но некоторые из них терпят неудачу, когда я добавляю Саксона в мой путь к классам. Все провалившиеся тесты используют Apache FOP для создания PDF-файла. Разница в том, что теперь некоторые сгенерированные вкладки (ключи отступа) вставляются в сгенерированный PDF (а не в видимое содержимое, я просто вижу их при сравнении байт-кода). Я думаю, что это странное поведение, потому что я все еще использую Xalan и ожидаю того же результата, что и когда у меня нет Saxon в моем классе. Так что еще изменится, когда Саксон будет в классе?

Когда я добавляю

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

по моим тестам, он снова работает с Saxon в classpath. Но это не решение для моей производственной среды, потому что я хочу динамически переключаться между двумя процессорами.

Так кто-нибудь знает, что еще меняется, когда я добавляю Saxon в мой путь к классам? Большое спасибо!

Обновление: Я установил флаг jaxp.debug и получил следующий вывод (используя Xalan с Saxon в classpath)

    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

Когда я удаляю саксон из пути к классам, я получаю следующий вывод:

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

Прочитав этот вопрос Я добавил предложенные строки, чтобы получить информацию обо всех фабриках. Когда я использую процессор xalan (с саксонским в пути к классам), я получаю

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 голосов
/ 06 сентября 2018

Я думаю, у вас должны быть некоторые преобразования, использующие 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();

в случаях, когда вы хотите вызвать саксонца. Если вы хотите принять решение динамически, то управляйте им, используя некоторую условную логику в вашем собственном коде.

...