Nano Hash - криптовалюты, майнинг, программирование

Саксон не может найти функцию: текущая группа

Я пытаюсь использовать Saxon с таблицами стилей XSLT и использовать примеры кода из спецификации XSLT2 (http://www.w3.org/TR/xslt20/#xsl-for-each-group)

<table xsl:version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <tr>
    <th>Position</th>
    <th>Country</th>
    <th>City List</th>
    <th>Population</th>
  </tr>
  <xsl:for-each-group select="cities/city" group-by="@country">
    <tr>
      <td><xsl:value-of select="position()"/></td>
      <td><xsl:value-of select="@country"/></td>
      <td>
        <xsl:value-of select="current-group()/@name" separator=", "/>
      </td>
      <td><xsl:value-of select="sum(current-group()/@pop)"/></td>
    </tr>
  </xsl:for-each-group>
</table>

Я использую следующее в своем pom.xml

<dependency>
  <groupId>net.sf.saxon</groupId>
  <artifactId>Saxon-HE</artifactId>
  <version>9.6.0-3</version>
</dependency>   

и код для его запуска:

    @Test
    public void testSaxonXslt2GroupTest1() throws Exception {

        File xml_file = Fixtures.XSLT2_TEST1_XML;
        File xsl_file = Fixtures.XSLT2_TEST1_XSL;


        TransformerFactory tfactory = net.sf.saxon.TransformerFactoryImpl.newInstance();
        Transformer transformer = tfactory.newTransformer(new StreamSource(xsl_file));
        File saxonDir = new File("target/saxon/");
        saxonDir.mkdirs();
        try {
            transformer.transform(new StreamSource(xml_file),  
                new StreamResult(new FileOutputStream(new File(saxonDir, "test1.xml"))));
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

Это выдает ошибку на выходной консоли

SystemId Unknown; Line #13; Column #70; Could not find function: current-group
SystemId Unknown; Line #13; Column #70; function token not found.
(Location of error unknown)java.lang.NullPointerException

Эта функция отсутствует в версии Saxon, которую я использую, или я делаю что-то не так?


  • Я не думаю, что это вызывает проблемы, но почему вы указали version="1.0"? 23.12.2014
  • Я думаю, что это ошибка транскрипции, и она должна быть 2.0. Я проверю свой реальный код 23.12.2014
  • Я запускаю локально с xsl:version=2.0 23.12.2014
  • Я пытаюсь воспроизвести это, но, поскольку XSLT имеет <xsl:value-of select="current-group()/@name" separator=",">, образец даже не имеет правильного формата. Когда я исправляю код на <xsl:value-of select="current-group()/@name" separator=","/>, Saxon выводит результат, по крайней мере, запуская его из командной строки. 23.12.2014
  • Спасибо за терпеливость. Мой код имеет правильно сформированный XML/XSL. буду переклеивать... 23.12.2014
  • Теперь я могу нормально запустить код с Saxon 9.6.0.3 HE из командной строки, он не сообщает об ошибках. Кто-то еще должен будет проверить или объяснить, почему он не работает для вас с вашим кодом Java. 23.12.2014
  • Теперь таблица стилей определенно верна и выдает правильный вывод, так что вы можете исключить ее как источник ошибки. 23.12.2014
  • Спасибо за ваше время. Полезно знать, что Saxon может выполнять обработку, если он правильно настроен. 23.12.2014

Ответы:


1

JAXP снова наносит удар! Проблема в том, что на самом деле вы не используете Saxon.

Когда вы делаете это:

factory = net.sf.saxon.TransformerFactoryImpl.newInstance();

это действительно выглядит так, как будто вы вызываете саксонский метод, не так ли? Но в Java статические методы не могут быть переопределены таким образом (я бы сделал это, если бы мог...). Вы просто вызываете метод newInstance() базового класса, который ищет в пути к классам первый найденный XSLT-процессор. Если вы хотите явно вызвать Saxon, гораздо лучше избегать поиска пути к классам, выполнив

factory = new net.sf.saxon.TransformerFactoryImpl();
23.12.2014
  • Спасибо. Теперь все имеет смысл. Существует опасность того, что есть несколько способов сделать это, и поэтому я в конечном итоге вырезал и вставлял известные примеры и путал вещи. Надеюсь, пример поможет другим понять это правильно 24.12.2014

  • 2

    Теперь я нашел то, что работает.

        @Test
        public void testSaxonXslt2GroupTest1() throws Exception {
    //      http://stackoverflow.com/questions/9925483/calling-java-from-xsl-saxon  
    
            File xml_file = Fixtures.XSLT2_TEST1_XML;
            File xsl_file = Fixtures.XSLT2_TEST1_XSL;
            LOG.debug(FileUtils.readFileToString(xsl_file));
    

    // замена полного имени класса подходом свойств, кажется, работает

            System.setProperty("javax.xml.transform.TransformerFactory",
                    "net.sf.saxon.TransformerFactoryImpl");
            TransformerFactory tfactory = TransformerFactory.newInstance();
    

    //

      Transformer transformer = tfactory.newTransformer(new StreamSource(xsl_file));
                File saxonDir = new File("target/saxon/");
                saxonDir.mkdirs();
                try {
                    transformer.transform(new StreamSource(xml_file),  
                        new StreamResult(new FileOutputStream(new File(saxonDir, "test1.xml"))));
                } catch (Throwable t) {
                    t.printStackTrace();
                }
            }
    

    Я думал, что использования точного конструктора будет достаточно, но, похоже, это не так.

    23.12.2014
  • Я думаю, вы можете либо напрямую сделать TransformerFactory tFactory = new TransformerFactoryImpl(); с import net.sf.saxon.TransformerFactoryImpl;, либо вам действительно нужно установить системное свойство. Метод newInstance унаследован, и его нельзя переопределить в saxonica. .com/html/documentation/javadoc/net/sf/saxon/. 23.12.2014
  • Спасибо - это, кажется, объясняет - может быть, это нужно как-то переопределить или поймать 23.12.2014
  • Если вы считаете, что это должно быть исправлено в Saxon, вы можете сообщить об ошибке в Saxonica или уведомить @MichaelKay. 23.12.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..