Example #1
0
// Produce a C.xmlXPathObjectPtr suitable for passing to libxml2
func (n Nodeset) ToXPathNodeset() (ret C.xmlXPathObjectPtr) {
	ret = C.xmlXPathNewNodeSet(nil)
	for _, node := range n {
		C.xmlXPathNodeSetAdd(ret.nodesetval, (*C.xmlNode)(node.NodePtr()))
	}
	return
}
Example #2
0
// Produce a C.xmlXPathObjectPtr marked as a ResultValueTree, suitable for passing to libxml2
func (n Nodeset) ToXPathValueTree() (ret C.xmlXPathObjectPtr) {
	if len(n) == 0 {
		ret = C.xmlXPathNewValueTree(nil)
		return
	}

	ret = C.xmlXPathNewValueTree(nil)
	for _, node := range n {
		C.xmlXPathNodeSetAdd(ret.nodesetval, (*C.xmlNode)(node.NodePtr()))
	}
	//this hack-ish looking line tells libxml2 not to free the RVT
	//if we don't do this we get horrible double-free crashes everywhere
	ret.boolval = 0
	return
}
Example #3
0
// Convert an arbitrary value into a C.xmlXPathObjectPtr
// Unrecognised and nil values are converted to empty node sets.
func ValueToXPathObject(val interface{}) (ret C.xmlXPathObjectPtr) {
	if val == nil {
		//return the empty node set
		ret = C.xmlXPathNewNodeSet(nil)
		return
	}
	switch v := val.(type) {
	case unsafe.Pointer:
		return (C.xmlXPathObjectPtr)(v)
	case []unsafe.Pointer:
		ptrs := v
		if len(ptrs) > 0 {
			//default - return a node set
			ret = C.xmlXPathNewNodeSet(nil)
			for _, p := range ptrs {
				C.xmlXPathNodeSetAdd(ret.nodesetval, (*C.xmlNode)(p))
			}
		} else {
			ret = C.xmlXPathNewNodeSet(nil)
			return
		}
	case float64:
		ret = C.xmlXPathNewFloat(C.double(v))
	case string:
		xpathBytes := GetCString([]byte(v))
		xpathPtr := unsafe.Pointer(&xpathBytes[0])
		ret = C.xmlXPathNewString((*C.xmlChar)(xpathPtr))
	default:
		typ := reflect.TypeOf(val)
		// if a pointer to a struct is passed, get the type of the dereferenced object
		if typ.Kind() == reflect.Ptr {
			typ = typ.Elem()
		}
		//log the unknown type, return an empty node set
		//fmt.Println("go-resolve wrong-type", typ.Kind())
		ret = C.xmlXPathNewNodeSet(nil)
	}
	return
}