JSqlParser, как разбить выражение
Предположим, у меня есть выражение формата
a>10 and b>20 and c>30
Я хочу получить список выражений следующим образом
a>10
b>20
c>30
Если я использую шаблон посетителя выражения, для посетителя AndExpression я написал что-то вроде
public void visit(AndExpression andExpression) {
andExpression.getLeftExpression().accept(this);
andExpression.getRightExpression().accept(this);
}
но это, однако, рекурсивно работает и входит в каждый из других методов шаблона посетителя. Как мне остановиться, когда получено меньшее выражение?
Если я просто использую getLeftExpressions() и getRightExpression(), то при первом запуске я получаю "a>10" слева и "b>20 и c>30" справа.
2 ответа
В вашем visit
метод, вы можете вернуть список Expression
для данного And
выражения. Так что просто верните список Expression
объект следующим образом:
public List<Expression> visit(AndExpression andExpression) {
List<Expression> list = new ArrayList<Expression>();
lex = andExpression.getLeftExpression();
list.add(lex);
rex = andExpression.getRightExpression();
subEx1 = rex.getLeftExpression();
subEx2 = rex.getRightExpression();
list.add(subEx1);
list.add(subEx2);
return list;
}
Два подвыражения получены из первого правого выражения.
JSqlParser анализирует ваше выражение следующим образом:
AndExpression
AndExpression
a>10
b>20
c>30
Мне любопытно посмотреть, какую версию вы используете, если рекурсия действительно будет в правом пункте, а не в левом. Я использую JSqlParser 0,9-SNAPSHOT. Тем не менее, в моей версии JSqlParser (и я думаю, во всех, потому что это LL-парсер), в других комментариях ответов предлагается кодовый блок
while(ex.getLeftExpression() != null) {
list.add(ex.getLeftExpression());
ex = ex.getRightExpression();
}
не будет работать. Он находит (или собирает):
a > 10 AND b > 20
который является AndExpression
и терпит неудачу на ex = ex.getRightExpression();
потому что право никогда не будет AndExpression
, Вот как работает JSqlParser. AndExpression
рекурсия будет в leftExpression
,
Итак, вот решение и небольшой тест вокруг него, используя JSqlParser V0.9-SNAPSHOT, который использует рекурсивный способ посетить эти AndExpressions
и распечатывает найденное выражение. Я не добавил его в List
, Прости меня за это.
public class JSqlParser1 {
public static void main(String[] args) throws JSQLParserException {
Expression expr = CCJSqlParserUtil.parseCondExpression("a>10 and b>20 and c>30");
expr.accept(new ExpressionVisitorAdapter() {
@Override
public void visit(AndExpression expr) {
if (expr.getLeftExpression() instanceof AndExpression) {
expr.getLeftExpression().accept(this);
} else {
System.out.println(expr.getLeftExpression());
}
System.out.println(expr.getRightExpression());
}
});
}
}
Этот печатает:
a > 10
b > 20
c > 30