0

我正在使用 JEXL 来评估一个字符串,如下所示:

'GroupName'.'ProductName'.'item'.'fields'.'duration'

其中 GroupName 和 ProductName 是字符串变量,而其余的是固定字符串。

我建立了一个上下文:Map<String, Map<String, CustomClass>>它最终如下所示:

GroupName >> ProductName >> CustomClass

在评估表达式之前,我会用空字符替换所有单引号。

问题:当ProductName本身包含点时,评估不起作用。

问题:有什么方法可以告诉 JEXL 引擎使用自定义字符而不是点作为分隔符来评估表达式?

更新:在有关速度的 Oracle 文档中,它指出:不要使用“。” 属性名称中的字符。如果我理解正确的 JEXL 使用 Velocity 解析表达式,是否意味着无法克服上述问题?

问候,文森佐

4

1 回答 1

0

JEXL does not use Velocity for parsing; JEXL was inspired by Velocity and JSP/EL (10 years ago). Anyhow, if you are able to use the most current JEXL code (ie compile JEXL 3.2 from the trunk), you should be able to remove the quotes only from the first member of your expression. Example test case follows. Cheers

public static class CustomEnzo {
    private final String name;

    public CustomEnzo(String nm) {
        this.name = nm;
    }
    public CustomEnzo getItem() {
        return this;
    }
    public String getName() {
        return name;
    }
}

@Test
public void testEnzo001() throws Exception {
    Map<String, Object> cmap = new TreeMap<>();
    Map<String, CustomEnzo> vmap = new TreeMap<>();
    vmap.put("ProductName", new CustomEnzo("000"));
    vmap.put("Product.Name", new CustomEnzo("001"));
    vmap.put("Product...Name", new CustomEnzo("002"));
    cmap.put("GroupName", vmap);
    JexlContext ctxt = new MapContext(cmap);
    JexlEngine jexl = new JexlBuilder().create();
    Object result;
    result = jexl.createExpression("GroupName.ProductName.item.name").evaluate(ctxt);
    Assert.assertEquals("000", result);
    result = jexl.createExpression("GroupName.'ProductName'.item.name").evaluate(ctxt);
    Assert.assertEquals("000", result);
    result = jexl.createExpression("GroupName.'Product.Name'.item.name").evaluate(ctxt);
    Assert.assertEquals("001", result);
    result = jexl.createExpression("GroupName.'Product...Name'.item.name").evaluate(ctxt);
    Assert.assertEquals("002", result);
    result = jexl.createExpression("GroupName.'Product...Name'.'item'.'name'").evaluate(ctxt);
    Assert.assertEquals("002", result);
}
于 2020-06-05T08:43:45.843 回答