func (xn *XMLNode) ToBool() (bool, error) {
	switch xn.ValueType() {
	case reflect.String:
		value, err := xn.ToString()
		if err != nil {
			return false, errors.New("can not convert value to bool")
		}
		return strconv.ParseBool(value)
	case reflect.Bool:
		return xn.Value.(bool), nil
	default:
		return false, errors.New("can not convert value to bool")
	}
}
ToBool convert the node value to bool.
If value is not valid bool, an error will be returned.
package xmlParser
import (
	"errors"
	"fmt"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"time"
	"github.com/clbanning/mxj"
)
type XMLNode struct {
	Value interface{}
	Path  string
}
func GenerateXMLNode(xmlBuffer []byte) (*XMLNode, error) {
	m, err := mxj.NewMapXml(xmlBuffer)
	xNode := XMLNode{Value: m.Old()}
	return &xNode, err
}
func (xn *XMLNode) CurrentKey() string {
	keys := strings.Split(xn.Path, ".")
	return keys[len(keys)-1]
}
func (xn *XMLNode) FindByKey(key string) []XMLNode {
	valuesMap := []XMLNode{}
	xnode, err := xn.ToMap()
	if err != nil {
		return valuesMap
	}
	paths := xnode.PathsForKey(key)
	for _, p := range paths {
		nodes := xn.FindByPath(p)
		valuesMap = append(valuesMap, nodes...)
	}
	return valuesMap
}
func (xn *XMLNode) FindByKeys(keys ...string) []XMLNode {
	valuesMap := []XMLNode{}
	if len(keys) <= 0 {
		return valuesMap
	}
	keysRegexp := regexp.MustCompile(
		`(^|\.)` + strings.Join(keys, `(\.(\w+\.)*)`) + `($|\.)`,
	)
	nodes := xn.FindByKey(keys[len(keys)-1])
	for _, node := range nodes {
		if keysRegexp.MatchString(node.Path) {
			valuesMap = append(valuesMap, node)
		}
	}
	return valuesMap
}
func (xn *XMLNode) FindByPath(path string) []XMLNode {
	valuesMap := []XMLNode{}
	xnode, err := xn.ToMap()
	if err != nil {
		return valuesMap
	}
	values, err := xnode.ValuesForPath(path)
	if err != nil {
		return valuesMap
	}
	for _, m := range values {
		node := XMLNode{Value: m, Path: path}
		valuesMap = append(valuesMap, node)
	}
	return valuesMap
}
func (xn *XMLNode) FindByFullPath(path string) []XMLNode {
	subPath := strings.Replace(path, xn.Path+".", "", 1)
	return xn.FindByPath(subPath)
}
func (xn *XMLNode) Elements() []string {
	xnode, err := xn.ToMap()
	if err != nil {
		return []string{}
	}
	elements, err := xnode.Elements("")
	if err != nil {
		return []string{}
	}
	return elements
}
func (xn *XMLNode) IsLeaf() bool {
	return reflect.TypeOf(xn.Value).Kind() != reflect.Map
}
func (xn *XMLNode) LeafPaths() []string {
	xnode, err := xn.ToMap()
	if err != nil {
		return []string{}
	}
	return xnode.LeafPaths()
}
func (xn *XMLNode) LeafNodes() []XMLNode {
	xnode, err := xn.ToMap()
	if err != nil {
		return []XMLNode{}
	}
	nodes := xnode.LeafNodes()
	lnodes := make([]XMLNode, len(nodes))
	for i, node := range nodes {
		lnodes[i] = XMLNode{
			Value: node.Value,
			Path:  node.Path,
		}
	}
	return lnodes
}
func (xn *XMLNode) ValueType() reflect.Kind {
	return reflect.TypeOf(xn.Value).Kind()
}
func (xn *XMLNode) ToMap() (mxj.Map, error) {
	if xn.ValueType() == reflect.Map {
		return mxj.Map(xn.Value.(map[string]interface{})), nil
	}
	return nil, errors.New("value is not a map")
}
func (xn *XMLNode) ToString() (string, error) {
	if xn.ValueType() == reflect.String {
		return xn.Value.(string), nil
	}
	return "", errors.New("value is not a valid string")
}
func (xn *XMLNode) ToInt() (int, error) {
	switch xn.ValueType() {
	case reflect.String:
		value, err := xn.ToString()
		if err != nil {
			return 0, errors.New("can not convert value to int")
		}
		return strconv.Atoi(value)
	case reflect.Int:
		return xn.Value.(int), nil
	default:
		return 0, errors.New("can not convert value to int")
	}
}
func (xn *XMLNode) ToFloat64() (float64, error) {
	switch xn.ValueType() {
	case reflect.String:
		value, err := xn.ToString()
		if err != nil {
			return 0.0, errors.New("can not convert value to float64")
		}
		return strconv.ParseFloat(value, 64)
	case reflect.Float64:
		return xn.Value.(float64), nil
	default:
		return 0.0, errors.New("can not convert value to float64")
	}
}