Esempio n. 1
0
/* {{{ 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);
	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "OO", &id, dom_xpath_class_entry, &doc, dom_document_class_entry) == FAILURE) {
		zend_restore_error_handling(&error_handling);
		return;
	}

	zend_restore_error_handling(&error_handling);
	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(id);
	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);
	}
}
Esempio n. 2
0
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, &register_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);
}
Esempio n. 3
0
File: node.c Progetto: IMSoP/php-src
static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
{
	zval *id;
	zval *xpath_array=NULL, *ns_prefixes=NULL;
	xmlNodePtr nodep;
	xmlDocPtr docp;
	xmlNodeSetPtr nodeset = NULL;
	dom_object *intern;
	zend_bool exclusive=0, with_comments=0;
	xmlChar **inclusive_ns_prefixes = NULL;
	char *file = NULL;
	int ret = -1;
	size_t file_len = 0;
	xmlOutputBufferPtr buf;
	xmlXPathContextPtr ctxp=NULL;
	xmlXPathObjectPtr xpathobjp=NULL;

	id = ZEND_THIS;
	if (mode == 0) {
		if (zend_parse_parameters(ZEND_NUM_ARGS(),
			"|bba!a!", &exclusive, &with_comments,
			&xpath_array, &ns_prefixes) == FAILURE) {
			return;
		}
	} else {
		if (zend_parse_parameters(ZEND_NUM_ARGS(),
			"s|bba!a!", &file, &file_len, &exclusive,
			&with_comments, &xpath_array, &ns_prefixes) == FAILURE) {
			return;
		}
	}

	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);

	docp = nodep->doc;

	if (! docp) {
		php_error_docref(NULL, E_WARNING, "Node must be associated with a document");
		RETURN_FALSE;
	}

	if (xpath_array == NULL) {
		if (nodep->type != XML_DOCUMENT_NODE) {
			ctxp = xmlXPathNewContext(docp);
			ctxp->node = nodep;
			xpathobjp = xmlXPathEvalExpression((xmlChar *) "(.//. | .//@* | .//namespace::*)", ctxp);
			ctxp->node = NULL;
			if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
				nodeset = xpathobjp->nodesetval;
			} else {
				if (xpathobjp) {
					xmlXPathFreeObject(xpathobjp);
				}
				xmlXPathFreeContext(ctxp);
				php_error_docref(NULL, E_WARNING, "XPath query did not return a nodeset.");
				RETURN_FALSE;
			}
		}
	} else {
		/*xpath query from xpath_array */
		HashTable *ht = Z_ARRVAL_P(xpath_array);
		zval *tmp;
		char *xquery;

		tmp = zend_hash_str_find(ht, "query", sizeof("query")-1);
		if (tmp && Z_TYPE_P(tmp) == IS_STRING) {
			xquery = Z_STRVAL_P(tmp);
		} else {
			php_error_docref(NULL, E_WARNING, "'query' missing from xpath array or is not a string");
			RETURN_FALSE;
		}

		ctxp = xmlXPathNewContext(docp);
		ctxp->node = nodep;

		tmp = zend_hash_str_find(ht, "namespaces", sizeof("namespaces")-1);
		if (tmp && Z_TYPE_P(tmp) == IS_ARRAY) {
			zval *tmpns;
			zend_string *prefix;

			ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(tmp), prefix, tmpns) {
				if (Z_TYPE_P(tmpns) == IS_STRING) {
					if (prefix) {
						xmlXPathRegisterNs(ctxp, (xmlChar *) ZSTR_VAL(prefix), (xmlChar *) Z_STRVAL_P(tmpns));
					}
				}
			} ZEND_HASH_FOREACH_END();
		}

		xpathobjp = xmlXPathEvalExpression((xmlChar *) xquery, ctxp);
		ctxp->node = NULL;
		if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
			nodeset = xpathobjp->nodesetval;
		} else {
			if (xpathobjp) {
				xmlXPathFreeObject(xpathobjp);
			}
			xmlXPathFreeContext(ctxp);
			php_error_docref(NULL, E_WARNING, "XPath query did not return a nodeset.");
			RETURN_FALSE;
		}
	}
Esempio n. 4
0
/* {{{ proto DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype);
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocument
Since: DOM Level 2
*/
PHP_METHOD(domimplementation, createDocument)
{
	zval *node = NULL, *rv = NULL;
	xmlDoc *docp;
	xmlNode *nodep;
	xmlDtdPtr doctype = NULL;
	xmlNsPtr nsptr = NULL;
	int ret, uri_len = 0, name_len = 0, errorcode = 0;
	char *uri, *name;
	char *prefix = NULL, *localname = NULL;
	dom_object *doctobj;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssO", &uri, &uri_len, &name, &name_len, &node, dom_documenttype_class_entry) == FAILURE) {
		return;
	}

	if (node != NULL) {
		DOM_GET_OBJ(doctype, node, xmlDtdPtr, doctobj);
		if (doctype->type == XML_DOCUMENT_TYPE_NODE) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid DocumentType object");
			RETURN_FALSE;
		}
		if (doctype->doc != NULL) {
			php_dom_throw_error(WRONG_DOCUMENT_ERR, 1 TSRMLS_CC);
			RETURN_FALSE;
		}
	} else {
		doctobj = NULL;
	}

	if (name_len > 0) {
		errorcode = dom_check_qname(name, &localname, &prefix, 1, name_len);
		if (errorcode == 0 && uri_len > 0 && ((nsptr = xmlNewNs(NULL, uri, prefix)) == NULL)) {
			errorcode = NAMESPACE_ERR;
		}
	}

	if (prefix != NULL) {
		xmlFree(prefix);
	}

	if (errorcode != 0) {
		if (localname != NULL) {
			xmlFree(localname);
		}
		php_dom_throw_error(errorcode, 1 TSRMLS_CC);
		RETURN_FALSE;
	}

	/* currently letting libxml2 set the version string */
	docp = xmlNewDoc(NULL);
	if (!docp) {
		if (localname != NULL) {
			xmlFree(localname);
		}
		RETURN_FALSE;
	}

	if (doctype != NULL) {
		docp->intSubset = doctype;
		doctype->parent = docp;
		doctype->doc = docp;
		docp->children = (xmlNodePtr) doctype;
		docp->last = (xmlNodePtr) doctype;
	}

	if (localname != NULL) {
		nodep = xmlNewDocNode (docp, nsptr, localname, NULL);
		if (!nodep) {
			if (doctype != NULL) {
				docp->intSubset = NULL;
				doctype->parent = NULL;
				doctype->doc = NULL;
				docp->children = NULL;
				docp->last = NULL;
			}
			xmlFreeDoc(docp);
			xmlFree(localname);
			/* Need some type of error here */
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected Error");
			RETURN_FALSE;
		}

		nodep->nsDef = nsptr;

		xmlDocSetRootElement(docp, nodep);
		xmlFree(localname);
	}

	DOM_RET_OBJ(rv, (xmlNodePtr) docp, &ret, NULL);

	if (doctobj != NULL) {
		doctobj->document = ((dom_object *)((php_libxml_node_ptr *)docp->_private)->_private)->document;
		php_libxml_increment_doc_ref((php_libxml_node_object *)doctobj, docp TSRMLS_CC);
	}
}