diff --git a/src/main/java/org/jsoup/select/QueryParser.java b/src/main/java/org/jsoup/select/QueryParser.java index 3b2b735696..b4dd513990 100644 --- a/src/main/java/org/jsoup/select/QueryParser.java +++ b/src/main/java/org/jsoup/select/QueryParser.java @@ -141,6 +141,7 @@ private void combinator(char combinator) { private String consumeSubQuery() { StringBuilder sq = StringUtil.borrowBuilder(); + boolean isNewQuery = false; while (!tq.isEmpty()) { if (tq.matches("(")) sq.append("(").append(tq.chompBalanced('(', ')')).append(")"); @@ -149,10 +150,18 @@ else if (tq.matches("[")) else if (tq.matchesAny(combinators)) if (sq.length() > 0) break; - else - tq.consume(); - else + else { + if (tq.consume()=='>') + isNewQuery = true; + } + else { + // If it is a new sub query of class, add '>' back into the query. + if (isNewQuery && tq.toString().charAt(0)=='.'){ + sq.append('>'); + isNewQuery = false; + } sq.append(tq.consume()); + } } return StringUtil.releaseBuilder(sq); } diff --git a/src/test/java/org/jsoup/select/QueryParserTest.java b/src/test/java/org/jsoup/select/QueryParserTest.java index 8c4db2348b..2209f6bc37 100644 --- a/src/test/java/org/jsoup/select/QueryParserTest.java +++ b/src/test/java/org/jsoup/select/QueryParserTest.java @@ -25,6 +25,21 @@ public class QueryParserTest { assertEquals("l2", doc.select(">body>p>strong,>body>*>li>strong").text()); } + @Test public void testConsumeSubQuery_Class() { + Document doc = Jsoup.parse("h" + + "
" + + "A" + + "B
" + + "
" + + "
"+ + "C" + + "D
"); + assertEquals("A B",doc.body().select(">.entry__header>.item1, >.entry__header>.item2").text()); + assertEquals("A B C D",doc.body().select(".entry__header>.item1, .entry__header>.item2").text()); + assertEquals("A B D",doc.body().select(">.entry__header>.item1, .entry__header>.item2").text()); + assertEquals("A B C",doc.body().select(".entry__header>.item1, >.entry__header>.item2").text()); + } + @Test public void testOrGetsCorrectPrecedence() { // tests that a selector "a b, c d, e f" evals to (a AND b) OR (c AND d) OR (e AND f)" // top level or, three child ands