首页 > 解决方案 > Spring DSL:在转换器中使用消息头

问题描述

我有像下面这样的 xml,在运行时我想动态处理。第一次先然后等等

<tag1> 
  <tag2> 
.
.
.
  </tag2>
  <tag2>
.
.
.
  </tag2>
</tag1>

CASE1:发送静态 xslt 参数的工作代码:

.transform(Transformers.xslt(this.config.getSome().getXslt(), xsltParameters(1 or 2)))

public Tuple2[] xsltParameters(int number)
{
    final SpelExpressionParser parser = new SpelExpressionParser();
    final List<Tuple2<String,Expression>> parameters = new ArrayList<>();

    parameters.add(Tuples.of("Id1", parser.parseRaw(String.format("headers['%s']",ID1))));
    parameters.add(Tuples.of("Id2", parser.parseRaw(String.format("headers['%s']",ID2))));
    parameters.add(Tuples.of("tagNumber", parser.parseRaw(String.format("%d",number))));

    return parameters.toArray(new Tuple2[]{});
}

以上工作正常,变压器可以转换 xslt。

CASE2:当我想传递动态号码时出错:

.transform(Message.class, m-> Transformers.xslt(this.config.getSome().getXslt(), xsltParameters())

xsltparametr(){
parameters.add(Tuples.of("tagNumber", 
parser.parseRaw(String.format("headers['%s']",COUNT))));
}

转换时出错:

test.xslt 的第 158 行出错(第 158 行之前工作正常) XPTY0004:不允许将多个项目的序列作为starts-with() 的第一个参数(“xxmmyty”、“xxmmyty”)

我的 xslt 在第 158 行

<xsl:if test="starts-with(xc:tag1/xc:tag2[$count]/xc:trade/xcml:header/xcml:Identifier/xcml:tradeId[@IdScheme='urn:abcd.something'], 'XYZ')" >
<xsl:value-of select="tag" />
</xsl:if>

在具有相同 xslt 文件的 CASE1 中,我可以传递上面的代码,但在动态传递(CASE2)的情况下,它会失败。

标签: springspring-integrationspring-integration-dslspring-dsl

解决方案


首先,看起来您使用的是足够旧的 Spring 版本。至少升级到5.0.x.

其次,不清楚你的xsltParameters(). 你对我们隐瞒,我们完全不知道你在那里做什么。虽然我们可以假设你完全基于这种方法:

@SafeVarargs
public static XsltPayloadTransformer xslt(Resource xsltTemplate,
                            Tuple2<String, Expression>... xslParameterMappings) {

因此,您在其中构建了xsltParameters()一个Tuple2. 好的。因此,访问您需要构建适当表达式的参数中的标头。

我确信它可以是FunctionExpression

.transform(Transformers.xslt(this.config.getSome().getXslt(), 
            Tuples.of("foo", new FunctionExpression<Message<?>>(m -> m.getHeader.get("int_val"))))).

您对 lambda 所做的操作不能与该工厂的变压器结合使用。

更新

您需要修改您的xsltParameters()以接受 a String。这将只是原始表达式表示。

因此,您的 CASE1 将是这样的:

.transform(Transformers.xslt(this.config.getSome().getXslt(), xsltParameters("'1'")))

字面意思表达

CASE2 将是这样的:

.transform(Transformers.xslt(this.config.getSome().getXslt(), xsltParameters("headers.int_val")))

推荐阅读