ErrPath error messages are now more expressive.
(Thanks @grahamking and @kisielk)
diff --git a/etree.go b/etree.go
index d7f0ffb..7a04095 100644
--- a/etree.go
+++ b/etree.go
@@ -21,13 +21,16 @@
NoIndent = -1
)
-var (
- // ErrXML is returned when XML parsing fails due to incorrect formatting.
- ErrXML = errors.New("etree: invalid XML format")
+// ErrXML is returned when XML parsing fails due to incorrect formatting.
+var ErrXML = errors.New("etree: invalid XML format")
- // ErrPath is returned when an invalid etree path is provided.
- ErrPath = errors.New("etree: invalid path")
-)
+// ErrPath is returned by path functions when an invalid etree path is provided.
+type ErrPath string
+
+// Error returns the string describing a path error.
+func (err ErrPath) Error() string {
+ return "etree: " + string(err)
+}
// A Token is an empty interface that represents an Element,
// Comment, CharData, or ProcInst.
diff --git a/path.go b/path.go
index f0c792a..9bc7774 100644
--- a/path.go
+++ b/path.go
@@ -54,7 +54,7 @@
func CompilePath(path string) (Path, error) {
var comp compiler
segments := comp.parsePath(path)
- if comp.err != nil {
+ if comp.err != ErrPath("") {
return Path{nil}, comp.err
}
return Path{segments}, nil
@@ -158,7 +158,7 @@
// A compiler generates a compiled path from a path string.
type compiler struct {
- err error
+ err ErrPath
}
// parsePath parses an XPath-like string describing a path
@@ -175,7 +175,7 @@
// Paths cannot be absolute
if strings.HasPrefix(path, "/") {
- c.err = ErrPath
+ c.err = ErrPath("paths cannot be absolute.")
return nil
}
@@ -183,7 +183,7 @@
var segments []segment
for _, s := range strings.Split(path, "/") {
segments = append(segments, c.parseSegment(s))
- if c.err != nil {
+ if c.err != ErrPath("") {
break
}
}
@@ -200,7 +200,7 @@
for i := 1; i < len(pieces); i++ {
fpath := pieces[i]
if fpath[len(fpath)-1] != ']' {
- c.err = ErrPath
+ c.err = ErrPath("path has invalid filter [brackets].")
break
}
seg.filters = append(seg.filters, c.parseFilter(fpath[:len(fpath)-1]))
@@ -227,7 +227,7 @@
// parseFilter parses a path filter contained within [brackets].
func (c *compiler) parseFilter(path string) filter {
if len(path) == 0 {
- c.err = ErrPath
+ c.err = ErrPath("path contains an empty filter expression.")
return nil
}
@@ -236,7 +236,7 @@
if eqindex >= 0 {
rindex := nextIndex(path, "'", eqindex+2)
if rindex != len(path)-1 {
- c.err = ErrPath
+ c.err = ErrPath("path has mismatched filter quotes.")
return nil
}
switch {
diff --git a/path_test.go b/path_test.go
index 2a52f0e..8e7537c 100644
--- a/path_test.go
+++ b/path_test.go
@@ -4,9 +4,7 @@
package etree
-import (
- "testing"
-)
+import "testing"
var testXML = `
<?xml version="1.0" encoding="UTF-8"?>
@@ -106,11 +104,11 @@
{"./bookstore/book[@category='COOKING']/title/../../book[4]/title", "Learning XML"},
// bad paths
- {"/bookstore", errorResult("etree: invalid path")},
- {"./bookstore/book[]", errorResult("etree: invalid path")},
- {"./bookstore/book[@category='WEB'", errorResult("etree: invalid path")},
- {"./bookstore/book[@category='WEB]", errorResult("etree: invalid path")},
- {"./bookstore/book[author]a", errorResult("etree: invalid path")},
+ {"/bookstore", errorResult("etree: paths cannot be absolute.")},
+ {"./bookstore/book[]", errorResult("etree: path contains an empty filter expression.")},
+ {"./bookstore/book[@category='WEB'", errorResult("etree: path has invalid filter [brackets].")},
+ {"./bookstore/book[@category='WEB]", errorResult("etree: path has mismatched filter quotes.")},
+ {"./bookstore/book[author]a", errorResult("etree: path has invalid filter [brackets].")},
}
func TestPath(t *testing.T) {