XSLT с запросом к базе данных

#java #xslt #xquery

#java #xslt #xquery

Вопрос:

Я некоторое время выполнял преобразование XML в своем Java-приложении, и мне все еще не ясно, какие есть опции и какой наилучший вариант — прочитать записи из базы данных и вставить их в мой преобразованный выходной файл.

Что я делал до сих пор, так это запрашивал базу данных Oracle с помощью XQuery, которая в результате выдала мне набор узлов. Затем я передал этот результат в качестве параметра преобразователю и запросил этот параметр во время преобразования, чтобы вставить данные в соответствующие узлы.

Является ли это лучшим способом сделать это? Моим базовым языком снова является Java. Каковы были бы другие варианты получения того же результата?

Также, я думаю, стоит упомянуть, что в большинстве случаев запрос к БД основан на содержимом исходного XML-файла.

Спасибо

Комментарии:

1. @L4zl0w: Без полного варианта использования такого рода вопросы проектирования субъективны. В зависимости от сложности преобразования, возможно, было бы лучше использовать только XQuery.

2. @Alejandro: К сожалению, у меня пока нет подробностей, поэтому я пытаюсь разобраться в своих возможностях. Когда вы ссылаетесь на XQuery, вы имеете в виду запустить XQuery и передать результат преобразователю в качестве параметра? Спасибо!

3. Что вас беспокоит в текущем дизайне? Для меня это выглядит нормально.

4. @road to yamburg: «Меня беспокоит только то, что это пока не работает.:) У меня возникли проблемы с передачей результирующего набора в надлежащем формате в transformer, чтобы я мог получить к нему доступ. И еще одна вещь, я должен сначала проанализировать xml, а затем создать xquery, который выдает мне несколько строк, в то время как, если я делаю это внутри transformer, я могу просто формировать запрос каждый раз, когда мне это нужно во время преобразования.

5. @L4zl0w: Я имел в виду запустить только один XQuery для завершения задачи.

Ответ №1:

Вы смотрели на расширения Saxon SQL, в частности на <sql:query> extension element?

Комментарии:

1. спасибо, я думаю, мне нужно что-то вроде этого. Похоже, у меня есть два варианта: XQuery, из которого я все еще не уверен, как получить доступ к SQL, и расширение Saxon SQL.

2. Похоже, что в Xalan также есть расширение sql! xml.apache.org/xalan/sql

Ответ №2:

Одна из возможностей заключается в создании экземпляра Java-объекта в вашем скрипте XSLT;

     <!-- Connection to the data provider. -->
    <xsl:variable name="provider" xmlns:java="http://xml.apache.org/xalan/java"
        select="java:my.sample.DataProvider.getInstance()" />
  

Использование его для предоставления данных позже в сценарии:

     <xsl:template match="node">
        <xsl:variable name="mydata" xmlns:java="http://xml.apache.org/xalan/java"
                    select="java:getdata($provider,  string(@attr))" />
  

Это вызвало бы метод getData(String) для объекта, созданного статическим getInstance() методом в вашем my.sample.DataProvider классе.

Вы можете использовать подобную настройку для получения значений из кэша (например, результатов запроса, которые вы пытаетесь передать в качестве параметра в вашей текущей настройке) или для выполнения запросов во время выполнения преобразования (предотвращая запросы к данным, которые не посещаются преобразованием.)

Комментарии:

1. Хотя это интересное упражнение для ума, я бы не советовал использовать что-либо подобное на самом деле. Сочетание проблем в самом лучшем виде.

2. @road to yamburg: не могли бы вы, пожалуйста, уточнить проблемы? можете ли вы придумать лучшее решение? Спасибо!

3. Сочетание проблем: доступ к базе данных и логика в одном фрагменте кода (XSLT). Правильный способ — получить данные из базы данных в одном месте, затем обработать их в другом месте, не обращая внимания на то, откуда они пришли. Упрощает внесение изменений (разделение), упрощает тестирование (mocks) и так далее. В XSLT можно многое сделать, поскольку это мощный язык, но если это можно сделать, это не значит, что это нужно делать.

4. Я согласен с @road в том, что разделение задач является важной проблемой и что вам не следует использовать подобную конструкцию для доступа к данным, подлежащим преобразованию. Однако я также считаю, что это правильный подход для ситуаций, когда для отображения первичных XML-данных используются несколько источников данных. (Лучше, чем предварительно обрабатывать ваш XML, чтобы определить, какие данные вы должны предлагать через параметры, которые дублируют вашу логику.) Доступ к данным развязан с использованием заводского шаблона. Объект provider должен предлагать абстракцию для доступа к данным, вы не должны использовать его как функцию DB.