Siblings offer one way to navigate the HTML parse tree sideways.
There is another way using next and previous elements.
Let's take a look at the soup.b element.
This is the b tag.
We know that the b tag has next siblings but when you access
the next_element property on the b tag,
this will go to the next navigable element,
which happens to be the NavigableString Tom.
Next_element does not navigate at the same level of the parse tree.
It goes down the tree as well to the next logical navigable element.
Let's understand this a little better.
For the b tag, let's access .next_element .next_element,
and we'll get Jerry, so we've navigated down the tree and then up the tree.
The next_element property goes deeper into the tree if possible and
then moves back up when we reach the leaf nodes.
And next_element is fundamentally different from how next_sibling works,
which navigates only at the same level.
We know that the html tag is the root of this document.
Let's take a look at the contents of the HTML that we are working with.
Now let's try and access the next element of this html tag.
Soup.html .next_element will go down the tree to the body tag.
The body element has no sibling.
It's the only child of the HTML element.
If you do soup.html .next_element .next_element,
that'll go further down the tree to the a tag,
which is the child of the body.
Every navigable element in your parse tree contains the next_elements property,
which basically gives you all of the elements that appear after this one.
Soup.a .next_elements gives you the b element,
the NavigableString inside the b element,
the i element, the NavigableString Jerry inside the i element,
and so on, basically every navigable element after the current one.
Just like the next_element,
the parse tree also supports the previous_element
property for every navigable element.
Soup.i .previous_element will give us the NavigableString Tom.
The previous_element goes down the parse tree to the
leaf node and then navigates up.
Let's try this once again.
Let's get the soup.i .previous_element .previous_element,
and this will give us the b tag.
So previous_element went down the parse tree and then up.
This is different from previous_sibling, which just navigates at the same level.
We've seen that previous_sibling returns None when there
are no siblings at the same level.
Just like previous_element, we have previous_elements as well.
You can take a current element and navigate all of the
elements that lie above it in the parse tree.
This will navigate the entire tree structure,
not just elements at the same level.
You can try this once again with soup.a .previous_elements,
and that gives you the body element, as well as the HTML element.