diff --git a/etree.go b/etree.go index 3cbb575..4fbebb6 100644 --- a/etree.go +++ b/etree.go @@ -1274,6 +1274,34 @@ func (e *Element) dup(parent *Element) Token { return ne } +// NextSibling returns this element's next sibling element. It returns nil if +// there is no next sibling element. +func (e *Element) NextSibling() *Element { + if e.parent == nil { + return nil + } + for i := e.index + 1; i < len(e.parent.Child); i++ { + if s, ok := e.parent.Child[i].(*Element); ok { + return s + } + } + return nil +} + +// PrevSibling returns this element's preceding sibling element. It returns +// nil if there is no preceding sibling element. +func (e *Element) PrevSibling() *Element { + if e.parent == nil { + return nil + } + for i := e.index - 1; i >= 0; i-- { + if s, ok := e.parent.Child[i].(*Element); ok { + return s + } + } + return nil +} + // Parent returns this element's parent element. It returns nil if this // element has no parent. func (e *Element) Parent() *Element { diff --git a/etree_test.go b/etree_test.go index 4c825ef..8ea9994 100644 --- a/etree_test.go +++ b/etree_test.go @@ -1587,3 +1587,46 @@ func TestValidateInput(t *testing.T) { } t.Run("ReadFromFile", func(t *testing.T) { runTests(t, readFromFile) }) } + +func TestSiblingElement(t *testing.T) { + doc := newDocumentFromString(t, ` `) + + root := doc.SelectElement("root") + a := root.SelectElement("a") + b := root.SelectElement("b") + c := root.SelectElement("c") + b1 := b.SelectElement("b1") + + tests := []struct { + e *Element + next *Element + prev *Element + }{ + {root, nil, nil}, + {a, b, nil}, + {b, c, a}, + {c, nil, b}, + {b1, nil, nil}, + } + + toString := func(e *Element) string { + if e == nil { + return "nil" + } + return e.Tag + } + + for i, test := range tests { + next := test.e.NextSibling() + if next != test.next { + t.Errorf("etree: test #%d unexpected NextSibling result.\n Expected: %s\n Received: %s\n", + i, toString(next), toString(test.next)) + } + + prev := test.e.PrevSibling() + if prev != test.prev { + t.Errorf("etree: test #%d unexpected PrevSibling result.\n Expected: %s\n Received: %s\n", + i, toString(prev), toString(test.prev)) + } + } +}