diff options
-rw-r--r-- | bs4/element.py | 13 | ||||
-rw-r--r-- | bs4/tests/test_tree.py | 13 |
2 files changed, 25 insertions, 1 deletions
diff --git a/bs4/element.py b/bs4/element.py index 75a76bb..6feced9 100644 --- a/bs4/element.py +++ b/bs4/element.py @@ -708,6 +708,17 @@ class PageElement(object): # Run the next token as a CSS selector against the # direct children of each tag in the current context. recursive_candidate_generator = lambda tag: tag.children + elif token == '~': + # Run the next token as a CSS selector against the + # siblings of each tag in the current context. + recursive_candidate_generator = lambda tag: tag.next_siblings + elif token == '+': + # For each tag in the current context, run the next + # token as a CSS selector against the tag's next + # sibling that's a tag. + def next_tag_sibling(tag): + yield tag.find_next_sibling(True) + recursive_candidate_generator = next_tag_sibling elif self.tag_name_re.match(token): # Just a tag name. @@ -761,7 +772,7 @@ class PageElement(object): yield child _use_candidate_generator = default_candidate_generator else: - _use_candidate_generator = lambda x: x.descendants + _use_candidate_generator = lambda tag: tag.descendants else: _use_candidate_generator = _candidate_generator diff --git a/bs4/tests/test_tree.py b/bs4/tests/test_tree.py index 47afb81..db5d602 100644 --- a/bs4/tests/test_tree.py +++ b/bs4/tests/test_tree.py @@ -1786,3 +1786,16 @@ class TestSoupSelector(TreeTest): def test_overspecified_child_id(self): self.assertSelects(".fancy #inner", ['inner']) self.assertSelects(".normal #inner", []) + + def test_adjacent_sibling_selector(self): + self.assertSelects('#p1 + h2', ['header2']) + self.assertSelects('#p1 + h2 + p', ['pmulti']) + self.assertSelects('#p1 + #header2 + .class1', ['pmulti']) + self.assertEqual([], self.soup.select('#p1 + p')) + + def test_general_sibling_selector(self): + self.assertSelects('#p1 ~ h2', ['header2', 'header3']) + self.assertSelects('#p1 ~ #header2', ['header2']) + self.assertSelects('#p1 ~ h2 + a', ['me']) + self.assertSelects('#p1 ~ h2 + [rel="me"]', ['me']) + self.assertEqual([], self.soup.select('#inner ~ h2')) |