我使用XQuery 3.0来转换传入的消息,以适应我的系统。XQuery是通过转换EIP从Apache路由调用的。
示例:
transform().xquery("resource:classpath:xquery/myxquery.xquery",String.class)
虽然转换没有问题,但是如果能够在转换过程中直接记录一些信息,这将是很好的,因为这在一定程度上是非常复杂的。
所以我想问一下,是否可以直接从 XQuery登录“ logback ”
我已经搜索了堆栈溢出,当然还搜索了https://www.w3.org/TR/xquery-30-use-cases/和其他来源,但是我只是找不到关于如何在Xquery中记录的任何信息。
我的项目结构是:
更新:为了在Apache框架中集成XQuery,我使用org.apache.camel:camel-saxon-starter:2.22.2。
发布于 2019-02-22 10:38:27
Update:由于fn:trace的使用有点难看,所以我进一步搜索,现在我使用来自Saxon的扩展机制来提供不同的日志功能,可以通过fn:trace访问:
有关更多信息,请参见文档:http://www.saxonica.com/documentation/#!extensibility/integratedfunctions/ext-full-J
下面是我在日志记录方面所做的工作(用Saxon测试,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并将其绑定到camel上下文中:
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")原始文章a.k.a如何覆盖fn:trace函数:
多亏了、Martin、,我尝试了fn:trace函数。问题是,默认情况下,它登录到System.err Printstream中,这不是我想要的,因为我想将fn:trace函数与Logback日志记录框架结合起来。
因此,我调试了net.sf.saxon.functions.Trace方法,并为我的项目设置找到了以下解决方案。
net.sf.saxon.trace.XQueryTraceListener扩展的自定义net.sf.saxon.trace.XQueryTraceListener,并以一种将带有constructType == 2041的InstructionInfo (用于用户跟踪)转发到SLF4J-API的方式实现enter和leave方法。例如(仅用于记录消息):@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 setTraceListener将自定义跟踪监听器设置为您的setTraceListener BeanXQueryEndpoint从camel调用xquery文件,因为只有在那里才能用一个选项:.to("xquery:/xquery/myxquery.xquery?configuration=#saxonConf")覆盖Configuration。不幸的是,transform().xquery(...)使用它自己的对象,而不可能配置它们。{fn:trace($element/text(),"Das ist ein Tracing Test")},并在日志中查看消息。https://stackoverflow.com/questions/54810888
复制相似问题