Ejemplo n.º 1
0
//export exec_xpath_function
func exec_xpath_function(ctxt C.xmlXPathParserContextPtr, nargs C.int) {
	function := C.GoString((*C.char)(unsafe.Pointer(ctxt.context.function)))
	namespace := C.GoString((*C.char)(unsafe.Pointer(ctxt.context.functionURI)))
	context := (*VariableScope)(ctxt.context.funcLookupData)

	argcount := int(nargs)
	var args []interface{}

	for i := 0; i < argcount; i = i + 1 {
		args = append(args, XPathObjectToValue(C.valuePop(ctxt)))
	}

	// arguments are popped off the stack in reverse order, so
	// we reverse the slice before invoking our callback
	if argcount > 1 {
		for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
			args[i], args[j] = args[j], args[i]
		}
	}

	// push the result onto the stack
	// if for some reason we are unable to resolve the
	// function we push an empty nodeset
	f := (*context).ResolveFunction(function, namespace)
	if f != nil {
		retval := f(*context, args)
		C.valuePush(ctxt, ValueToXPathObject(retval))
	} else {
		ret := C.xmlXPathNewNodeSet(nil)
		C.valuePush(ctxt, ret)
	}

}
Ejemplo n.º 2
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
}
Ejemplo n.º 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
}