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) {