#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.