func XPathObjectToValue(obj C.xmlXPathObjectPtr) (result interface{}) { rt := XPathObjectType(C.getXPathObjectType(obj)) switch rt { case XPATH_NODESET, XPATH_XSLT_TREE: if nodesetPtr := obj.nodesetval; nodesetPtr != nil { if nodesetSize := int(nodesetPtr.nodeNr); nodesetSize > 0 { nodes := make([]unsafe.Pointer, nodesetSize) for i := 0; i < nodesetSize; i++ { nodes[i] = unsafe.Pointer(C.fetchNode(nodesetPtr, C.int(i))) } result = nodes return } } result = nil case XPATH_NUMBER: obj = C.xmlXPathConvertNumber(obj) result = float64(obj.floatval) case XPATH_BOOLEAN: obj = C.xmlXPathConvertBoolean(obj) result = obj.boolval != 0 default: obj = C.xmlXPathConvertString(obj) result = C.GoString((*C.char)(unsafe.Pointer(obj.stringval))) } return }
//need to add an error as a return value b/c xpath evaluation can return error func (xpath *XPath) Evaluate(nodePtr unsafe.Pointer, xpathExpr *Expression) (nodes []unsafe.Pointer, err error) { if nodePtr == nil { //evaluating xpath on a nil node returns no result. return } xpath.ContextPtr.node = (*C.xmlNode)(nodePtr) if xpath.ResultPtr != nil { C.xmlXPathFreeObject(xpath.ResultPtr) } xpath.ResultPtr = C.xmlXPathCompiledEval(xpathExpr.Ptr, xpath.ContextPtr) if xpath.ResultPtr == nil { err = errors.New("err in evaluating xpath: " + xpathExpr.String()) return } if nodesetPtr := xpath.ResultPtr.nodesetval; nodesetPtr != nil { if nodesetSize := int(nodesetPtr.nodeNr); nodesetSize > 0 { nodes = make([]unsafe.Pointer, nodesetSize) for i := 0; i < nodesetSize; i++ { nodes[i] = unsafe.Pointer(C.fetchNode(nodesetPtr, C.int(i))) } } } return }
func (obj *XPathObject) Results() chan *Node { channel := make(chan *Node) go func(obj *XPathObject, channel chan *Node) { if obj.Ptr._type != 1 { close(channel) return } for i := 0; i < int(obj.Ptr.nodesetval.nodeNr); i++ { channel <- makeNode(C.fetchNode(obj.Ptr.nodesetval, C.int(i))) } close(channel) }(obj, channel) return channel }
// Get the XPath result as a nodeset. func (xpath *XPath) ResultAsNodeset() (nodes []unsafe.Pointer, err error) { if xpath.ResultPtr == nil { return } if xpath.ReturnType() != XPATH_NODESET { err = errors.New("Cannot convert XPath result to nodeset") } if nodesetPtr := xpath.ResultPtr.nodesetval; nodesetPtr != nil { if nodesetSize := int(nodesetPtr.nodeNr); nodesetSize > 0 { nodes = make([]unsafe.Pointer, nodesetSize) for i := 0; i < nodesetSize; i++ { nodes[i] = unsafe.Pointer(C.fetchNode(nodesetPtr, C.int(i))) } } } return }
func (xpath *XPath) Evaluate(nodePtr unsafe.Pointer, xpathExpr *Expression) (nodes []unsafe.Pointer) { if nodePtr == nil { return } xpath.ContextPtr.node = (*C.xmlNode)(nodePtr) if xpath.ResultPtr != nil { C.xmlXPathFreeObject(xpath.ResultPtr) } xpath.ResultPtr = C.xmlXPathCompiledEval(xpathExpr.Ptr, xpath.ContextPtr) if nodesetPtr := xpath.ResultPtr.nodesetval; nodesetPtr != nil { if nodesetSize := int(nodesetPtr.nodeNr); nodesetSize > 0 { nodes = make([]unsafe.Pointer, nodesetSize) for i := 0; i < nodesetSize; i++ { nodes[i] = unsafe.Pointer(C.fetchNode(nodesetPtr, C.int(i))) } } } return }
// Query Do a xpath query with the given context // returns a slice of nodes func (xp *Xp) Query(context *C.xmlNode, path string) (nodes []*C.xmlNode) { var xmlXPathObject *C.xmlXPathObject if xmlXPathObject = xp.xmlXPathEvalExpression(context, path); xmlXPathObject == nil { return nil } defer C.xmlXPathFreeNodeSetList(xmlXPathObject) // curtesy of https://github.com/moovweb/gokogiri/blob/master/xpath/xpath.go#L164 if nodesetPtr := xmlXPathObject.nodesetval; nodesetPtr != nil { if nodesetSize := int(nodesetPtr.nodeNr); nodesetSize > 0 { nodes = make([]*C.xmlNode, nodesetSize) for i := 0; i < nodesetSize; i++ { nodes[i] = C.fetchNode(nodesetPtr, C.int(i)) } } } return }