Skip to content

Commit 06f9e30

Browse files
committed
fix example run error on playground. #110
1 parent a139d00 commit 06f9e30

File tree

1 file changed

+213
-10
lines changed

1 file changed

+213
-10
lines changed

doc_test.go

Lines changed: 213 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,235 @@
11
package xpath_test
22

33
import (
4+
"bytes"
45
"fmt"
56

67
"github.com/antchfx/xpath"
78
)
89

9-
// XPath package example.
10+
type NodeType uint
11+
12+
const (
13+
DocumentNode NodeType = iota
14+
ElementNode
15+
TextNode
16+
)
17+
18+
type Node struct {
19+
Parent, FirstChild, LastChild, PrevSibling, NextSibling *Node
20+
21+
Type NodeType
22+
Data string
23+
}
24+
25+
func (n *Node) Value() string {
26+
if n.Type == TextNode {
27+
return n.Data
28+
}
29+
30+
var buff bytes.Buffer
31+
var output func(*Node)
32+
output = func(node *Node) {
33+
if node.Type == TextNode {
34+
buff.WriteString(node.Data)
35+
}
36+
for child := node.FirstChild; child != nil; child = child.NextSibling {
37+
output(child)
38+
}
39+
}
40+
output(n)
41+
return buff.String()
42+
}
43+
44+
func (parent *Node) AddChild(n *Node) {
45+
n.Parent = parent
46+
n.NextSibling = nil
47+
if parent.FirstChild == nil {
48+
parent.FirstChild = n
49+
n.PrevSibling = nil
50+
} else {
51+
parent.LastChild.NextSibling = n
52+
n.PrevSibling = parent.LastChild
53+
}
54+
55+
parent.LastChild = n
56+
}
57+
58+
type NodeNavigator struct {
59+
curr, root *Node
60+
}
61+
62+
func (n *NodeNavigator) NodeType() xpath.NodeType {
63+
switch n.curr.Type {
64+
case TextNode:
65+
return xpath.TextNode
66+
case DocumentNode:
67+
return xpath.RootNode
68+
}
69+
return xpath.ElementNode
70+
}
71+
72+
func (n *NodeNavigator) LocalName() string {
73+
return n.curr.Data
74+
}
75+
76+
func (n *NodeNavigator) Prefix() string {
77+
return ""
78+
}
79+
80+
func (n *NodeNavigator) NamespaceURL() string {
81+
return ""
82+
}
83+
84+
func (n *NodeNavigator) Value() string {
85+
switch n.curr.Type {
86+
case ElementNode:
87+
return n.curr.Value()
88+
case TextNode:
89+
return n.curr.Data
90+
}
91+
return ""
92+
}
93+
94+
func (n *NodeNavigator) Copy() xpath.NodeNavigator {
95+
n2 := *n
96+
return &n2
97+
}
98+
99+
func (n *NodeNavigator) MoveToRoot() {
100+
n.curr = n.root
101+
}
102+
103+
func (n *NodeNavigator) MoveToParent() bool {
104+
if node := n.curr.Parent; node != nil {
105+
n.curr = node
106+
return true
107+
}
108+
return false
109+
}
110+
111+
func (n *NodeNavigator) MoveToNextAttribute() bool {
112+
return true
113+
}
114+
115+
func (n *NodeNavigator) MoveToChild() bool {
116+
if node := n.curr.FirstChild; node != nil {
117+
n.curr = node
118+
return true
119+
}
120+
return false
121+
}
122+
123+
func (n *NodeNavigator) MoveToFirst() bool {
124+
for {
125+
node := n.curr.PrevSibling
126+
if node == nil {
127+
break
128+
}
129+
n.curr = node
130+
}
131+
return true
132+
}
133+
134+
func (n *NodeNavigator) String() string {
135+
return n.Value()
136+
}
137+
138+
func (n *NodeNavigator) MoveToNext() bool {
139+
if node := n.curr.NextSibling; node != nil {
140+
n.curr = node
141+
return true
142+
}
143+
return false
144+
}
145+
146+
func (n *NodeNavigator) MoveToPrevious() bool {
147+
if node := n.curr.PrevSibling; node != nil {
148+
n.curr = node
149+
return true
150+
}
151+
return false
152+
}
153+
154+
func (n *NodeNavigator) MoveTo(other xpath.NodeNavigator) bool {
155+
node, ok := other.(*NodeNavigator)
156+
if !ok || node.root != n.root {
157+
return false
158+
}
159+
160+
n.curr = node.curr
161+
return true
162+
}
163+
164+
// XPath package example. See more xpath implements package:
165+
// https://github.com/antchfx/htmlquery
166+
// https://github.com/antchfx/xmlquery
167+
// https://github.com/antchfx/jsonquery
10168
func Example() {
169+
/***
170+
?xml version="1.0" encoding="UTF-8"?>
171+
<bookstore>
172+
<book>
173+
<title>Everyday Italian</title>
174+
<author>Giada De Laurentiis</author>
175+
<year>2005</year>
176+
<price>30.00</price>
177+
</book>
178+
<book>
179+
<title>Harry Potter</title>
180+
<author>J K. Rowling</author>
181+
<year>2005</year>
182+
<price>29.99</price>
183+
</book>
184+
</bookstore>
185+
**/
186+
187+
// Here, for begin test, we should create a document
188+
books := []struct {
189+
title string
190+
author string
191+
year int
192+
price float64
193+
}{
194+
{title: "Everyday Italian", author: "Giada De Laurentiis", year: 2005, price: 30.00},
195+
{title: "Harry Potter", author: "J K. Rowling", year: 2005, price: 29.99},
196+
}
197+
bookstore := &Node{Data: "bookstore", Type: ElementNode}
198+
for _, v := range books {
199+
book := &Node{Data: "book", Type: ElementNode}
200+
title := &Node{Data: "title", Type: ElementNode}
201+
title.AddChild(&Node{Data: v.title, Type: TextNode})
202+
book.AddChild(title)
203+
author := &Node{Data: "author", Type: ElementNode}
204+
author.AddChild(&Node{Data: v.author, Type: TextNode})
205+
book.AddChild(author)
206+
year := &Node{Data: "year", Type: ElementNode}
207+
year.AddChild(&Node{Data: fmt.Sprintf("%d", v.year), Type: TextNode})
208+
book.AddChild(year)
209+
price := &Node{Data: "price", Type: ElementNode}
210+
price.AddChild(&Node{Data: fmt.Sprintf("%f", v.price), Type: TextNode})
211+
book.AddChild(price)
212+
bookstore.AddChild(book)
213+
}
214+
var doc = &Node{}
215+
doc.AddChild(bookstore)
216+
var root xpath.NodeNavigator = &NodeNavigator{curr: doc, root: doc}
11217
expr, err := xpath.Compile("count(//book)")
218+
// using Evaluate() method
12219
if err != nil {
13220
panic(err)
14221
}
15-
var root xpath.NodeNavigator
16-
// using Evaluate() method
17222
val := expr.Evaluate(root) // it returns float64 type
18223
fmt.Println(val.(float64))
19224

20225
// using Evaluate() method
21-
expr = xpath.MustCompile("//book")
22-
val = expr.Evaluate(root) // it returns NodeIterator type.
23-
iter := val.(*xpath.NodeIterator)
24-
for iter.MoveNext() {
25-
fmt.Println(iter.Current().Value())
26-
}
226+
expr = xpath.MustCompile("sum(//price)")
227+
val = expr.Evaluate(root) // output total price
228+
fmt.Println(val.(float64))
27229

28230
// using Select() method
29-
iter = expr.Select(root) // it always returns NodeIterator object.
231+
expr = xpath.MustCompile("//book")
232+
iter := expr.Select(root) // it always returns NodeIterator object.
30233
for iter.MoveNext() {
31234
fmt.Println(iter.Current().Value())
32235
}

0 commit comments

Comments
 (0)