Skip to content

Commit 3cbab97

Browse files
committed
Merge PR #119
2 parents 511abd5 + 02c01b0 commit 3cbab97

3 files changed

Lines changed: 42 additions & 3 deletions

File tree

query.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ func (a *ancestorQuery) Select(t iterator) NodeNavigator {
201201
func (a *ancestorQuery) Evaluate(t iterator) interface{} {
202202
a.Input.Evaluate(t)
203203
a.iterator = nil
204+
// Reset the table when re-evaluating to ensure clean state
205+
a.table = nil
204206
return a
205207
}
206208

@@ -829,6 +831,8 @@ func (f *filterQuery) Select(t iterator) NodeNavigator {
829831

830832
func (f *filterQuery) Evaluate(t iterator) interface{} {
831833
f.Input.Evaluate(t)
834+
// Reset the position map when re-evaluating to ensure clean state
835+
f.positmap = nil
832836
return f
833837
}
834838

xpath_axes_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,28 @@ func Test_ancestor_predicate(t *testing.T) {
6565
test_xpath_elements(t, doc, `//span/ancestor::section[2]`, 4, 9)
6666
}
6767

68+
func Test_ancestor_predicate_chain(t *testing.T) {
69+
doc := createElement(0, "",
70+
createElement(1, "html",
71+
createElementAttr(2, "body", map[string]string{"itemscope": "", "itemtype": "Article"},
72+
createElement(3, "section",
73+
createElementAttr(4, "span", map[string]string{"itemprop": "author"}),
74+
createElementAttr(5, "div", map[string]string{"itemscope": "", "itemtype": "Comment"},
75+
createElementAttr(6, "span", map[string]string{"itemprop": "author"}),
76+
createElement(7, "div",
77+
createElementAttr(8, "span", map[string]string{"itemprop": "author"}),
78+
),
79+
),
80+
),
81+
),
82+
),
83+
)
84+
85+
// Find elements marked as "author" property whose closest "itemscope" ancestor is of "Comment" type.
86+
// This should find "span" elements on lines 6 and 8, but not line 4 since that one is under "Article".
87+
test_xpath_elements(t, doc, `//*[@itemprop="author"][ancestor::*[@itemscope][1][@itemtype="Comment"]]`, 6, 8)
88+
}
89+
6890
func Test_ancestor_or_self(t *testing.T) {
6991
// Expected the value is [2, 3, 8, 13], but got [3, 2, 8, 13]
7092
test_xpath_elements(t, employee_example, `//employee/ancestor-or-self::*`, 3, 2, 8, 13)

xpath_test.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"fmt"
66
"math"
7+
"reflect"
78
"sort"
89
"strings"
910
"testing"
@@ -41,10 +42,14 @@ func (t testQuery) Properties() queryProp {
4142

4243
func test_xpath_elements(t *testing.T, root *TNode, expr string, expected ...int) {
4344
result := selectNodes(root, expr)
44-
assertEqual(t, len(expected), len(result))
4545

46-
for i := 0; i < len(expected); i++ {
47-
assertEqual(t, expected[i], result[i].lines)
46+
var gotLines []int
47+
for i := 0; i < len(result); i++ {
48+
gotLines = append(gotLines, result[i].lines)
49+
}
50+
51+
if !reflect.DeepEqual(gotLines, expected) {
52+
t.Fatalf("expected lines %+v, got %+v", expected, gotLines)
4853
}
4954
}
5055

@@ -587,6 +592,14 @@ func (n *TNode) getAttribute(key string) string {
587592
return ""
588593
}
589594

595+
func createElementAttr(line int, name string, attrs map[string]string, children ...*TNode) *TNode {
596+
el := createElement(line, name, children...)
597+
for k, v := range attrs {
598+
el.addAttribute(k, v)
599+
}
600+
return el
601+
}
602+
590603
func createElement(line int, name string, children ...*TNode) *TNode {
591604
nodeType := ElementNode
592605
if name == "" {

0 commit comments

Comments
 (0)