JEXL 如何用自定义分隔符替换点
JEXL how to replace dot with a custom separator
我正在使用 JEXL 来评估字符串,如下所示:
'GroupName'.'ProductName'.'item'.'fields'.'duration'
其中 GroupName 和 ProductName 是字符串变量,其余是固定字符串。
我构建了一个上下文:Map<String, Map<String, CustomClass>>
最终如下所示:
GroupName >> ProductName >> CustomClass
在计算表达式之前,我将所有单引号替换为空字符。
问题:当 ProductName 本身包含一个点时,评估不起作用。
问题:有什么方法可以告诉 JEXL 引擎使用自定义字符而不是点作为分隔符来计算表达式?
更新:在有关 velocity 的 oracle 文档中指出:不要使用 '.' 属性 名字中的字符。如果我理解正确的 JEXL 使用 Velocity 来解析表达式,是否意味着没有办法解决上述问题?
此致,
文森佐
JEXL 不 使用 Velocity 进行解析; JEXL 的灵感来自 Velocity 和 JSP/EL(10 年前)。
无论如何,如果您能够使用最新的 JEXL 代码(即从主干编译 JEXL 3.2),您应该只能从表达式的第一个成员中删除引号。
示例测试用例如下。
干杯
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);
}
我正在使用 JEXL 来评估字符串,如下所示:
'GroupName'.'ProductName'.'item'.'fields'.'duration'
其中 GroupName 和 ProductName 是字符串变量,其余是固定字符串。
我构建了一个上下文:Map<String, Map<String, CustomClass>>
最终如下所示:
GroupName >> ProductName >> CustomClass
在计算表达式之前,我将所有单引号替换为空字符。
问题:当 ProductName 本身包含一个点时,评估不起作用。
问题:有什么方法可以告诉 JEXL 引擎使用自定义字符而不是点作为分隔符来计算表达式?
更新:在有关 velocity 的 oracle 文档中指出:不要使用 '.' 属性 名字中的字符。如果我理解正确的 JEXL 使用 Velocity 来解析表达式,是否意味着没有办法解决上述问题?
此致, 文森佐
JEXL 不 使用 Velocity 进行解析; JEXL 的灵感来自 Velocity 和 JSP/EL(10 年前)。 无论如何,如果您能够使用最新的 JEXL 代码(即从主干编译 JEXL 3.2),您应该只能从表达式的第一个成员中删除引号。 示例测试用例如下。 干杯
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);
}