Вход с XQuery - PullRequest
       31

Вход с XQuery

0 голосов
/ 21 февраля 2019

Я использую XQuery 3.0 , чтобы преобразовать входящее сообщение для соответствия моей системе.XQuery вызывается из Apache Camel Маршрута через преобразование EIP.

Пример:
transform().xquery("resource:classpath:xquery/myxquery.xquery",String.class)

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

Поэтому я хотел спросить, можно ли войти "в" logback напрямую из XQuery ?

Я уже искал stackoverflow и, конечно, https://www.w3.org/TR/xquery-30-use-cases/ и другие источники, но я просто не смог найти ни одногоинформация о как регистрировать в Xquery.

Структура моего проекта:

  • Приложение Spring-Boot 2
  • Apache-Camel as Routingframework
  • Logback as Logging framework

Обновление : для интеграции XQuery в Apache-Camel Framework я использую org.apache.camel:camel-saxon-starter:2.22.2.

1 Ответ

0 голосов
/ 22 февраля 2019

Обновление : поскольку использование fn:trace было довольно уродливым, я продолжил поиск, и теперь я использую механизм расширения от Saxon для предоставления различных функций ведения журнала, к которым можно получить доступ через xquery:

Для получения дополнительной информации см. Документацию: http://www.saxonica.com/documentation/#!extensibility/integratedfunctions/ext-full-J

Вот что я сделал для регистрации (протестировано с Saxon-HE, Camel не является обязательным, я просто использую его по совпадению):

Первый шаг:

Расширение класса net.sf.saxon.lib.ExtensionFunctionDefinition

public class XQueryInfoLogFunctionDefinition extends ExtensionFunctionDefinition{

    private static final Logger log = LoggerFactory.getLogger(XQueryInfoLogFunctionDefinition.class);

    private final XQueryInfoExtensionFunctionCall functionCall = new XQueryInfoExtensionFunctionCall();

    private static final String PREFIX = "log";

    @Override
    public StructuredQName getFunctionQName() {
        return new StructuredQName(PREFIX, "http://thehandofnod.com/saxon-extension", "info");
    }

    @Override
    public SequenceType[] getArgumentTypes() {
        return new SequenceType[] { SequenceType.SINGLE_STRING };
    }

    @Override
    public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) {
        return SequenceType.VOID;
    }

    @Override
    public ExtensionFunctionCall makeCallExpression() {
        return functionCall;
    }

}

Второй шаг:

Реализация класса FunctionCall

public class XQueryInfoExtensionFunctionCall extends ExtensionFunctionCall {

    private static final Logger log = LoggerFactory.getLogger(XQueryInfoLogFunctionDefinition.class);

    @Override
    public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
        if (arguments != null && arguments.length > 0) {
            log.info(((StringValue) arguments[0]).getStringValue());
        } else
            throw new IllegalArgumentException("We need a message");
        return EmptySequence.getInstance();
    }
}

Третий шаг:

Сконфигурируйте SaxonConfiguration и привяжите ее в контекст верблюда:

    public static void main(String... args) throws Exception {
        Main main = new Main();

        Configuration saxonConfig = Configuration.newConfiguration(); 
        saxonConfig.registerExtensionFunction(new XQueryInfoLogFunctionDefinition());

        main.bind("saxonConfig", saxonConfig);
        main.addRouteBuilder(new MyRouteBuilder());
        main.run(args);
    }

Четвертый шаг:

Определите SaxonConfig в вашей точке XQueryEndpoint: .to("xquery:test.xquery?configuration=#saxonConfig");

Пятый шаг:

Назовите это в своем xquery:

declare namespace log="http://thehandofnod.com/saxon-extension";
log:info("Das ist ein INFO test")

Оригинальный пост aka Как переписать fn:trace Функцию:

Спасибо Martin Honnen Я попробовал функцию fn:trace.Проблема заключалась в том, что по умолчанию он входит в System.err Printstream, и это не то, что я хотел, потому что я хотел объединить функцию fn:trace с Logback Logging-Framework.

ИтакЯ отладил методы net.sf.saxon.functions.Trace и пришел к следующему решению для настройки моего проекта:

  1. Напишите пользовательский TraceListener, который простирается от net.sf.saxon.trace.XQueryTraceListener и реализует методы enter и leaveтаким образом, что InstructionInfo с constructType == 2041 (для user-trace ) перенаправляется в SLF4J-API.Пример (только для регистрации сообщения):
@Override
    public void enter(InstructionInfo info, XPathContext context) {
        // no call to super to keep it simple.
        String nachricht = (String) info.getProperty("label");
        if (info.getConstructType() == 2041 && StringUtils.hasText(nachricht)) {
            getLogger().info(nachricht);
        }
    }

    @Override
    public void leave(InstructionInfo info) {
        // no call to super to keep it simple.
    }

установить пользовательский прослушиватель трассировки в ваш net.sf.saxon.Configuration Bean через setTraceListener

Вызовите ваш файл xquery от верблюда через XQueryEndpointпотому что только там можно перезаписать Configuration с помощью опции: .to("xquery:/xquery/myxquery.xquery?configuration=#saxonConf").К сожалению, transform().xquery(...) использует свои собственные объекты без возможности их настройки.

вызовите {fn:trace($element/text(),"Das ist ein Tracing Test")} в вашем xquery и увидите сообщение в своем журнале.

...