访客方式始终是一种方式。如果你想获得括号深度,你可以坚持:
public void visit(Parenthesis parenthesis)
要获得你想要的输出,有点棘手。我实现了一个简单的例子,只考虑了 AND 和 OR。我不使用 ExpressionVisitorAdapter,而是使用 ExpressionDeParser,它负责表达式打印。这样,您可以根据需要修改生成的输出。
public static void main(String args[]) throws JSQLParserException {
Expression expr = CCJSqlParserUtil.parseCondExpression("(a=1 AND (b=2 OR (c=3 AND d=4))) OR e=2");
StringBuilder b = new StringBuilder();
expr.accept(new ExpressionDeParser(null, b) {
int depth = 0;
@Override
public void visit(Parenthesis parenthesis) {
if (parenthesis.isNot()) {
getBuffer().append("NOT");
}
depth++;
parenthesis.getExpression().accept(this);
depth--;
}
@Override
public void visit(OrExpression orExpression) {
visitBinaryExpr(orExpression, "OR");
}
@Override
public void visit(AndExpression andExpression) {
visitBinaryExpr(andExpression, "AND");
}
private void visitBinaryExpr(BinaryExpression expr, String operator) {
if (expr.isNot()) {
getBuffer().append("NOT");
}
if (!(expr.getLeftExpression() instanceof OrExpression)
&& !(expr.getLeftExpression() instanceof AndExpression)
&& !(expr.getLeftExpression() instanceof Parenthesis)) {
getBuffer().append(StringUtils.repeat("-", depth)).append(">");
}
expr.getLeftExpression().accept(this);
getBuffer().append("\n").append(StringUtils.repeat("-", depth)).append(">");
getBuffer().append(operator).append("\n");
if (!(expr.getRightExpression() instanceof OrExpression)
&& !(expr.getRightExpression() instanceof AndExpression)
&& !(expr.getRightExpression() instanceof Parenthesis)) {
getBuffer().append(StringUtils.repeat("-", depth)).append(">");
}
expr.getRightExpression().accept(this);
}
});
System.out.println(b);
}
如您所见,括号访问者改变了深度。困难的部分在visitBinaryExpression
. 复杂的 instanceof 逻辑源自使用 And/OrExpression 进行输出。由于对于一个文本行visitBinaryExpression
可能会发生多次调用,因此必须从最外面的部分进行缩进。
如果您想改进 JSqlParser 已解析语句的打印,您的更新应该转到解析器。