2016-06-21 3 views
0

Как преобразовать несколько объектов XML-документа ввода с помощью одного сценария преобразования XSL с использованием процессора Saxon9HE в Java-приложение?Преобразование нескольких входных XML-документов с помощью XSLT в Java-приложении с использованием API Saxon9HE

Я нашел способ преобразования нескольких входных файлов XML из файловой системы с помощью сценария XSLT here, но я не могу понять, как передать несколько загруженных объектов XML-документа в приложение Java с использованием API Saxon9HE. Для одного документа XML мой код выглядит так и работает:

Processor proc = new Processor(false); 

    XsltCompiler comp = proc.newXsltCompiler(); 

    try { 
     XsltExecutable exp = comp.compile(new StreamSource(stylesheetFile)); 

     XdmNode source = proc.newDocumentBuilder().build(new DOMSource(inputXML));   
     Serializer out = proc.newSerializer(); 

     out.setOutputProperty(Serializer.Property.METHOD, "xml"); 
     out.setOutputProperty(Serializer.Property.INDENT, "yes"); 
     out.setOutputFile(new File(outputFilename)); 

     XsltTransformer trans = exp.load(); 

     trans.setInitialContextNode(source); 
     trans.setDestination(out); 
     trans.transform(); 
    } catch (SaxonApiException e) { 
     e.printStackTrace(); 
    } 
+0

В приведенной таблице стилей используются некоторые параметры с именами файлов или URI, которые вы можете передать. Таким образом, вы можете использовать http://www.saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/XsltTransformer.html#setParameter (net.sf.saxon.s9api.QName,% 20net.sf.saxon.s9api.XdmValue) для установки таких параметров. –

+0

Спасибо. Но разве это не означает, что я могу только передавать файлы из файловой системы или Интернета через имя еще раз? Вместо этого я хочу передать объекты Java XML Document, загруженные и обработанные из другого источника. Должен ли я сохранять их в XML-файлах в файловой системе, чтобы передавать их в Saxon Transformer? – scholt

+0

Если вы хотите создать документ в своем приложении, вы также можете это сделать, возможно, вам придется изменить '' to '' в ссылочной таблице стилей, а затем вы можете установить параметр с именем 'doc2' в' XdmNode', который вы создаете в своем приложении, используя метод 'setParameter'. Поскольку у вас, кажется, есть узлы DOM, вы даже можете передать их напрямую, но я не уверен, что это более чистый подход, я уверен, с вопросом, помеченным как саксон, Майкл Кей расскажет вам. –

ответ

0

Первый пункт: избегайте DOM, если можете. Когда вы используете Saxon, лучше всего позволить Saxon построить дерево документа; это будет намного более эффективно. Если вам действительно нужно использовать внешнюю древовидную модель, XOM и JDOM2 намного эффективнее DOM.

Если вы хотите предоставить DOM в качестве ввода, у вас есть два варианта: вы можете скопировать его в саксонское дерево или вы можете обернуть его как саксонское дерево. Используйте DocumentBuilder.build() в первом случае, DocumentBuilder.wrap() во втором. Использование функции build() дает вам более высокую начальную стоимость, но сама трансформация быстрее.

Если вы хотите передать предварительно построенные деревья в преобразование, объявите параметр с помощью <xsl:param name="x" as="document-node()"/>, а затем вызовите преобразование, используя transformer.setParameter(new QName('x'), doc) где doc - это экземпляр XdmNode. Вы должны сами создать XdmNode, используя DocumentBuilder.

(Кроме того, если вы хотите получить доступ к документам в таблице стилей с помощью функций doc() или document(), вы можете придумать схему именования URI и реализовать это в URIResolver. Когда doc ('my: uri'), ваш URIResolver уведомляется, и он должен отвечать объекту Source.Если у вас уже есть XdmNode, вы можете вернуть XdmNode.asSource(), чтобы вернуть это дерево документа в результате вашего URIResolver.)

+0

Большое спасибо! Это действительно то, что я искал! Я должен использовать объекты DOM прямо сейчас, потому что мне нужна библиотека Java, которая возвращает данные XML в этой форме. Однако один вопрос: если я укажу загруженные деревья XML через «transformer.setParameter (новый метод QName ('x'), doc), должен ли я передать одно из деревьев как« initialContextNode »? У меня создалось впечатление, что это будет включать это конкретное дерево дважды (один раз через setParameter и один раз через setInitialContextNode), но при этом он пропускает SaxonApiException (нужен исходный документ, начальный шаблон или начальная функция). – scholt

+0

@scholt, эта таблица стилей, которую вы связали, ожидает первоначальный документ как контекстный узел, а затем два дополнительных документа в качестве параметров. Если вы хотите работать только с параметрами, вам нужно использовать именованный шаблон в качестве отправной точки (например, ' ...'). –

+0

@scholt - Если вам это нужно, у меня есть пример использования начального именованного шаблона с s9api в этом ответе: http://stackoverflow.com/questions/33788966/xslt-2-0-tokenize-and-group –