Пример #1
0
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
}
Пример #2
0
//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
}
Пример #3
0
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
}
Пример #4
0
// 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
}
Пример #5
0
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
}
Пример #6
0
// 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
}