Как использовать XSLT 3.0 из приложения Java?

Общий код Java, который я использую для обработки файлов XSLT и XML:

public static final String transformXmlDocument(String inputXmlString,
            File xsltFile) {

        TransformerFactory factory = TransformerFactory.newInstance();
        StreamSource xslt = new StreamSource(xsltFile);

        StreamSource text = new StreamSource(new StringReader(inputXmlString));
        StringWriter writer = new StringWriter();
        StreamResult textOP = new StreamResult(writer);

        try {
            Transformer transformer = factory.newTransformer(xslt);
            transformer.transform(text, textOP);
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e2) {
            e2.printStackTrace();
        }
        String results = writer.toString();

        return results;
}

Мне нужно обработать XSLT версии 3.0, чтобы использовать следующую функцию:

синтаксический анализ-xml-фрагмент ()

Это вызывает ошибку для этой версии XSLT, говоря:

parse-xml-fragment () не найден как функция

Мой входной XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data>
  <![CDATA[<pi>hi</pi>]]>
</data>

Код XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:data="http://example.com/data"
     xmlns:text="http://exselt.net/text"
     xmlns:err="http://www.w3.org/2005/xqt-errors"
     exclude-result-prefixes="xs xsl data text err"
     version="3.0">

<xsl:output indent="yes"/>

     <xsl:template match="/">
         <xsl:variable name="sample">
            <xsl:copy-of select="parse-xml-fragment('&lt;gi&gt;surface&lt;/gi&gt;&lt;gi&gt;surface&lt;/gi&gt;&lt;gi&gt;surface&lt;/gi&gt;')" />
         </xsl:variable>
         <final>
            <xsl:copy-of select="data/pi"/>
             <xsl:for-each select="$sample/gi">
                 <pi><xsl:value-of select="."/></pi>
            </xsl:for-each> 
         </final>
     </xsl:template>

</xsl:stylesheet>

ожидаемый результат:

<final>
    <pi>hi</pi>
    <pi>surface</pi>
    <pi>surface</pi>
    <pi>surface</pi>
  </final>

Может ли кто-нибудь предложить решение?


person Wilvasini    schedule 28.06.2017    source источник


Ответы (1)


Вам нужно будет убедиться, что Saxon 9.8 HE или PE или EE находится на вашем пути к классу, HE доступен на Sourceforge и Maven, коммерческие выпуски PE и EE с сайта saxonica.com. См. http://saxonica.com/html/documentation/about/installationjava/installingjava.html, а также http://saxonica.com/html/documentation/using-xsl/embedding/jaxp-transformation.html, которые рекомендуют после установки определенной версии использовать, например, http://saxonica.com/html/documentation/javadoc/net/sf/saxon/TransformerFactoryImpl.html напрямую, вместо того, чтобы полагаться на механизм загрузчика классов JAXP, поэтому, если у вас установлен Saxon 9.8 HE, вы можете заменить

    TransformerFactory factory = TransformerFactory.newInstance();

с участием

    TransformerFactory factory = new net.sf.saxon.TransformerFactoryImpl();
person Martin Honnen    schedule 28.06.2017
comment
спасибо за ваш быстрый ответ, я добавил зависимость от maven: ‹! - mvnrepository.com/ artifact / net.sf.saxon / Saxon-HE - ›‹dependency› ‹groupId› net.sf.saxon ‹/groupId› ‹artifactId› Saxon-HE ‹/artifactId› ‹version› 9.8.0- 1 ‹/version› ‹/dependency› Также заменил класс TransformerFactory, как упоминалось, но я все еще получаю сообщение об ошибке, что он не находит parse-xml-fragment () как функцию. Я что-то упускаю? - person Wilvasini; 28.06.2017
comment
Отредактируйте свой вопрос и покажите минимальные, но полные фрагменты входных XML-данных, XSLT-кода вместе с точным сообщением об ошибке, что позволит нам воспроизвести проблему. Вы ничего не передаете parse-xml-fragment? - person Martin Honnen; 28.06.2017
comment
Я отредактировал вопрос в соответствии с просьбой, сэр, когда я запускаю тот же код из командной строки, он работает, но не в eclipse - person Wilvasini; 28.06.2017
comment
Не торопитесь, чтобы добавить минимальные, но полные фрагменты, которые позволят нам воспроизвести проблему. <xsl:copy-of select"data/pi"/> даже не является правильным синтаксисом XML. И я не думаю, что XSLT, который вы опубликовали, содержит 36 строк. Есть ли шанс, что у вас есть другие, более старые версии Saxon на пути класса? - person Martin Honnen; 28.06.2017
comment
сообщение об ошибке: javax.xml.transform.TransformerConfigurationException: не удалось скомпилировать таблицу стилей. Обнаружена 1 ошибка. в net.sf.saxon.PreparedStylesheet.prepare (PreparedStylesheet.java:153) в net.sf.saxon.TransformerFactoryImpl.newTemplates (TransformerFactoryImpl.java:137) в net.sf.saxon.TransformerFactoryImplformer.java.transformerFactoryImpl.new ) в com.translation.xslt.CustomXsltTransformer.transformXmlDocument (CustomXsltTransformer.java:60) в com.translationProcessRequest.TestClass.main (TestClass.java:105) - person Wilvasini; 28.06.2017
comment
извините, я обновил сообщение об ошибке и вопрос соответственно - person Wilvasini; 28.06.2017
comment
Что ж, <xsl:copy-of select"data/pi"/> должно быть <xsl:copy-of select="data/pi"/>, чтобы быть синтаксически правильным XML / XSLT. Чтобы иметь смысл в семантическом вводе, вы скорее захотите <xsl:copy-of select="data/parse-xml-fragment(.)/pi"/>. - person Martin Honnen; 28.06.2017
comment
Что касается того, когда я запускаю тот же код из командной строки, он работает, но не в eclipse, кому-то еще нужно помочь выяснить, что не так с вашей настройкой в ​​Eclipse, убедитесь, что у вас в проекте только Saxon 9.8, а не более ранние версии, как Что ж. - person Martin Honnen; 28.06.2017
comment
В вашем комментарии отображается трассировка стека от Saxon, поэтому, по крайней мере, мы знаем, что Saxon загружается. Мы не знаем, какая версия Saxon, и я подозреваю, что это не 9.8, потому что номера строк не подходят. Трассировка стека бесполезна (она только говорит о том, что были обнаружены ошибки компиляции): вам действительно нужен файл журнала, показывающий, что такое ошибки компиляции. Вероятно, это будет где-то в вашей конфигурации Eclipse. Но я думаю, что ошибки компиляции сообщат вам только о том, что конструкции XSLT 3.0 не распознаются, чего и следовало ожидать, если была загружена неправильная версия Saxon. - person Michael Kay; 28.06.2017
comment
Чтобы узнать, какая версия Saxon находится в пути к классам, вызовите статический метод net.sf.saxon.Version.getProductVersion(). - person Michael Kay; 28.06.2017
comment
я получаю версию 8.9 в maven, я добавил: ‹version› 9.8.0-1 ‹/version› - person Wilvasini; 28.06.2017
comment
Ниже приводится вся информация, напечатанная из eclipse: xslt версия 2.0 название продукта SAXON версия продукта 8.9 моя версия xslt отличается от 3.0 как мне обновить ее? - person Wilvasini; 28.06.2017