/* {{{ proto void DOMXPath::__construct(DOMDocument doc) U */ PHP_METHOD(domxpath, __construct) { zval *id, *doc; xmlDocPtr docp = NULL; dom_object *docobj; dom_xpath_object *intern; xmlXPathContextPtr ctx, oldctx; zend_error_handling error_handling; zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC); if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_xpath_class_entry, &doc, dom_document_class_entry) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); DOM_GET_OBJ(docp, doc, xmlDocPtr, docobj); ctx = xmlXPathNewContext(docp); if (ctx == NULL) { php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); RETURN_FALSE; } intern = Z_XPATHOBJ_P(id); if (intern != NULL) { oldctx = (xmlXPathContextPtr)intern->dom.ptr; if (oldctx != NULL) { php_libxml_decrement_doc_ref((php_libxml_node_object *) &intern->dom TSRMLS_CC); xmlXPathFreeContext(oldctx); } xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "functionString", (const xmlChar *) "http://php.net/xpath", dom_xpath_ext_function_string_php); xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "function", (const xmlChar *) "http://php.net/xpath", dom_xpath_ext_function_object_php); intern->dom.ptr = ctx; ctx->userData = (void *)intern; intern->dom.document = docobj->document; php_libxml_increment_doc_ref((php_libxml_node_object *) &intern->dom, docp TSRMLS_CC); } }
/* {{{ proto DOMXPath::__construct(DOMDocument doc) U */ PHP_METHOD(domxpath, __construct) { zval *doc; xmlDocPtr docp = NULL; dom_object *docobj; dom_xpath_object *intern; xmlXPathContextPtr ctx, oldctx; if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "O", &doc, dom_document_class_entry) == FAILURE) { return; } DOM_GET_OBJ(docp, doc, xmlDocPtr, docobj); ctx = xmlXPathNewContext(docp); if (ctx == NULL) { php_dom_throw_error(INVALID_STATE_ERR, 1); RETURN_FALSE; } intern = Z_XPATHOBJ_P(ZEND_THIS); if (intern != NULL) { oldctx = (xmlXPathContextPtr)intern->dom.ptr; if (oldctx != NULL) { php_libxml_decrement_doc_ref((php_libxml_node_object *) &intern->dom); xmlXPathFreeContext(oldctx); } xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "functionString", (const xmlChar *) "http://php.net/xpath", dom_xpath_ext_function_string_php); xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "function", (const xmlChar *) "http://php.net/xpath", dom_xpath_ext_function_object_php); intern->dom.ptr = ctx; ctx->userData = (void *)intern; intern->dom.document = docobj->document; php_libxml_increment_doc_ref((php_libxml_node_object *) &intern->dom, docp); } }
static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ { zval *id, retval, *context = NULL; xmlXPathContextPtr ctxp; xmlNodePtr nodep = NULL; xmlXPathObjectPtr xpathobjp; size_t expr_len, nsnbr = 0, xpath_type; dom_xpath_object *intern; dom_object *nodeobj; char *expr; xmlDoc *docp = NULL; xmlNsPtr *ns = NULL; zend_bool register_node_ns = 1; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|O!b", &id, dom_xpath_class_entry, &expr, &expr_len, &context, dom_node_class_entry, ®ister_node_ns) == FAILURE) { return; } intern = Z_XPATHOBJ_P(id); ctxp = (xmlXPathContextPtr) intern->dom.ptr; if (ctxp == NULL) { php_error_docref(NULL, E_WARNING, "Invalid XPath Context"); RETURN_FALSE; } docp = (xmlDocPtr) ctxp->doc; if (docp == NULL) { php_error_docref(NULL, E_WARNING, "Invalid XPath Document Pointer"); RETURN_FALSE; } if (context != NULL) { DOM_GET_OBJ(nodep, context, xmlNodePtr, nodeobj); } if (!nodep) { nodep = xmlDocGetRootElement(docp); } if (nodep && docp != nodep->doc) { php_error_docref(NULL, E_WARNING, "Node From Wrong Document"); RETURN_FALSE; } ctxp->node = nodep; if (register_node_ns) { /* Register namespaces in the node */ ns = xmlGetNsList(docp, nodep); if (ns != NULL) { while (ns[nsnbr] != NULL) nsnbr++; } } ctxp->namespaces = ns; ctxp->nsNr = nsnbr; xpathobjp = xmlXPathEvalExpression((xmlChar *) expr, ctxp); ctxp->node = NULL; if (ns != NULL) { xmlFree(ns); ctxp->namespaces = NULL; ctxp->nsNr = 0; } if (! xpathobjp) { RETURN_FALSE; } if (type == PHP_DOM_XPATH_QUERY) { xpath_type = XPATH_NODESET; } else { xpath_type = xpathobjp->type; } switch (xpath_type) { case XPATH_NODESET: { int i; xmlNodeSetPtr nodesetp; array_init(&retval); if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval)) { for (i = 0; i < nodesetp->nodeNr; i++) { xmlNodePtr node = nodesetp->nodeTab[i]; zval child; if (node->type == XML_NAMESPACE_DECL) { xmlNsPtr curns; xmlNodePtr nsparent; nsparent = node->_private; curns = xmlNewNs(NULL, node->name, NULL); if (node->children) { curns->prefix = xmlStrdup((xmlChar *) node->children); } if (node->children) { node = xmlNewDocNode(docp, NULL, (xmlChar *) node->children, node->name); } else { node = xmlNewDocNode(docp, NULL, (xmlChar *) "xmlns", node->name); } node->type = XML_NAMESPACE_DECL; node->parent = nsparent; node->ns = curns; } php_dom_create_object(node, &child, &intern->dom); add_next_index_zval(&retval, &child); } } php_dom_create_interator(return_value, DOM_NODELIST); nodeobj = Z_DOMOBJ_P(return_value); dom_xpath_iter(&retval, nodeobj); break; } case XPATH_BOOLEAN: RETVAL_BOOL(xpathobjp->boolval); break; case XPATH_NUMBER: RETVAL_DOUBLE(xpathobjp->floatval) break; case XPATH_STRING: RETVAL_STRING((char *) xpathobjp->stringval); break; default: RETVAL_NULL(); break; } xmlXPathFreeObject(xpathobjp); }