-
/* {{{ proto boolean dom_attr_is_id();
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-isId
Since: DOM Level 3
*/
PHP_FUNCTION(dom_attr_is_id)
{
- DOM_NOT_IMPLEMENTED();
+ zval *id;
+ dom_object *intern;
+ xmlAttrPtr attrp;
+ xmlNodePtr nodep;
+
+ DOM_GET_THIS_OBJ(attrp, id, xmlAttrPtr, intern);
+
+ nodep = attrp->parent;
+
+ if (xmlIsID(attrp->doc, nodep, attrp)) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
}
/* }}} end dom_attr_is_id */
xmlNsPtr nsptr;
int ret, uri_len = 0, name_len = 0;
char *uri, *name;
- xmlChar *localname = NULL;
+ char *localname = NULL, *prefix = NULL;
int errorcode;
dom_object *intern;
return;
}
- nsptr = dom_get_ns(uri, name, uri_len, name_len, &errorcode, (char **) &localname);
+ errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
+
if (errorcode == 0) {
- if (nsptr != NULL) {
- dom_set_old_ns(docp, nsptr);
- nodep = xmlNewDocNode (docp, nsptr, localname, NULL);
- } else {
- nodep = xmlNewDocNode (docp, NULL, name, NULL);
+ nodep = xmlNewDocNode (docp, NULL, localname, NULL);
+ if (nodep != NULL) {
+ nsptr = xmlSearchNsByHref (nodep->doc, nodep, uri);
+ if (nsptr == NULL) {
+ nsptr = dom_get_ns(nodep, uri, &errorcode, prefix);
+ }
+ xmlSetNs(nodep, nsptr);
}
}
- if (localname != NULL) {
- xmlFree(localname);
+
+ xmlFree(localname);
+ if (prefix != NULL) {
+ xmlFree(prefix);
}
if (errorcode != 0) {
+ if (nodep != NULL) {
+ xmlFreeNode(nodep);
+ }
php_dom_throw_error(errorcode, &return_value TSRMLS_CC);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Namespace");
RETURN_FALSE;
RETURN_FALSE;
}
+
+ nodep->ns = nsptr;
+
DOM_RET_OBJ(rv, nodep, &ret, intern);
}
/* }}} end dom_document_create_element_ns */
{
zval *id, *rv = NULL;
xmlDocPtr docp;
- xmlNodePtr nodep = NULL;
+ xmlNodePtr nodep = NULL, root;
xmlNsPtr nsptr;
int ret, uri_len = 0, name_len = 0;
char *uri, *name;
- xmlChar *localname = NULL;
+ char *localname = NULL, *prefix = NULL;
dom_object *intern;
int errorcode;
return;
}
- nsptr = dom_get_ns(uri, name, uri_len, name_len, &errorcode, (char **) &localname);
- if (errorcode == 0) {
- if (nsptr != NULL) {
+ root = xmlDocGetRootElement(docp);
+ if (root != NULL) {
+ errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
+ if (errorcode == 0) {
nodep = (xmlNodePtr) xmlNewDocProp(docp, localname, NULL);
- dom_set_old_ns(docp, nsptr);
if (nodep != NULL) {
+ nsptr = xmlSearchNsByHref (nodep->doc, root, uri);
+ if (nsptr == NULL) {
+ nsptr = dom_get_ns(root, uri, &errorcode, prefix);
+ }
xmlSetNs(nodep, nsptr);
}
- } else {
- nodep = (xmlNodePtr) xmlNewDocProp(docp, name, NULL);
}
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Missing Root Element");
+ RETURN_FALSE;
}
- if (localname != NULL) {
- xmlFree(localname);
+
+ xmlFree(localname);
+ if (prefix != NULL) {
+ xmlFree(prefix);
}
if (errorcode != 0) {
+ if (nodep != NULL) {
+ xmlFreeProp((xmlAttrPtr) nodep);
+ }
php_dom_throw_error(errorcode, &return_value TSRMLS_CC);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Namespace");
RETURN_FALSE;
xmlNode *nodep;
xmlDtdPtr doctype = NULL;
xmlNsPtr nsptr = NULL;
- int ret, uri_len = 0, name_len = 0;
+ int ret, uri_len = 0, name_len = 0, errorcode = 0;
char *uri, *name;
- xmlChar *prefix = NULL, *localname = NULL;
- xmlURIPtr uristruct;
+ 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) == FAILURE) {
}
}
- if (uri_len > 0 || name_len > 0 || doctype != NULL) {
- if (name_len == 0 && uri_len > 0) {
- php_dom_throw_error(NAMESPACE_ERR, &return_value TSRMLS_CC);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Namespace");
+ 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 (name_len > 0) {
- uristruct = xmlParseURI(name);
- if (uristruct->opaque != NULL) {
- prefix = xmlStrdup(uristruct->scheme);
- localname = xmlStrdup(uristruct->opaque);
- if (xmlStrchr(localname, (xmlChar) ':') != NULL) {
- php_dom_throw_error(NAMESPACE_ERR, &return_value TSRMLS_CC);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Namespace");
- xmlFreeURI(uristruct);
- xmlFree(prefix);
- xmlFree(localname);
- RETURN_FALSE;
- }
- if (!strcmp (prefix, "xml") && strcmp(uri, XML_XML_NAMESPACE)) {
- php_dom_throw_error(NAMESPACE_ERR, &return_value TSRMLS_CC);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Namespace");
- xmlFreeURI(uristruct);
- xmlFree(prefix);
- xmlFree(localname);
- RETURN_FALSE;
- }
- } else {
- localname = xmlStrdup(name);
- }
-
- /* TODO: Test that localname has no invalid chars
- php_dom_throw_error(INVALID_CHARACTER_ERR, TSRMLS_CC);
- */
-
- xmlFreeURI(uristruct);
+ }
- if (uri_len > 0) {
- if ((nsptr = xmlNewNs(NULL, uri, prefix)) == NULL) {
- php_dom_throw_error(NAMESPACE_ERR, &return_value TSRMLS_CC);
- if (prefix != NULL) {
- xmlFree(prefix);
- }
- xmlFree(localname);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Namespace");
- RETURN_FALSE;
- }
+ if (prefix != NULL) {
+ xmlFree(prefix);
+ }
- }
- if (prefix != NULL) {
- xmlFree(prefix);
- }
+ if (errorcode != 0) {
+ if (localname != NULL) {
+ xmlFree(localname);
}
+ php_dom_throw_error(errorcode, &return_value TSRMLS_CC);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Namespace");
+ RETURN_FALSE;
}
/* currently letting libxml2 set the version string */
xmlNsPtr nsptr;
int ret, uri_len = 0, name_len = 0;
char *uri, *name;
- xmlChar *localname = NULL;
+ char *localname = NULL, *prefix = NULL;
dom_object *intern;
int errorcode = 0;
RETURN_FALSE;
}
- nsptr = xmlSearchNsByHref (elemp->doc, elemp, uri);
- if (nsptr == NULL) {
- nsptr = dom_get_ns(uri, name, uri_len, name_len, &errorcode, (char **) &localname);
- if (nsptr != NULL) {
- dom_set_old_ns(elemp->doc, nsptr);
- }
- }
+ errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
+
if (errorcode == 0) {
- if (nsptr != NULL) {
+ nodep = (xmlNodePtr) xmlHasNsProp(elemp, localname, uri);
+ if (nodep != NULL) {
+ node_list_unlink(nodep->children TSRMLS_CC);
+ }
+ nsptr = xmlSearchNsByHref(elemp->doc, elemp, uri);
+ while (nsptr && nsptr->prefix == NULL) {
+ nsptr = nsptr->next;
+ }
+ if (nsptr == NULL) {
+ if (prefix == NULL) {
+ errorcode = NAMESPACE_ERR;
+ } else {
+ nsptr = dom_get_ns(elemp, uri, &errorcode, prefix);
+ }
+ }
+
+ if (errorcode == 0) {
nodep = (xmlNodePtr) xmlSetNsProp(elemp, nsptr, localname, NULL);
- } else {
- nodep = (xmlNodePtr) xmlSetProp(elemp, name, NULL);
}
}
- if (localname != NULL) {
- xmlFree(localname);
+
+ xmlFree(localname);
+ if (prefix != NULL) {
+ xmlFree(prefix);
}
if (errorcode != 0) {
}
xmlAddChild(nodep, (xmlNodePtr) attrp);
- if (existattrp == NULL) {
- xmlReconciliateNs(nodep->doc, nodep);
- }
/* Returns old property if removed otherwise NULL */
if (existattrp != NULL) {
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
ns = nodep->ns;
- if (ns != NULL) {
- if (ns->prefix) {
- str = (char *) ns->prefix;
- }
+ if (ns != NULL && ns->prefix) {
+ str = (char *) ns->prefix;
}
break;
default:
switch (nodep->type) {
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
- ns = nodep->ns;
- strURI = NULL;
- if (nodep->ns != NULL) {
- strURI = (char *) nodep->ns->href;
- }
prefix = Z_STRVAL_P(newval);
- if (strURI == NULL ||
- (!strcmp (prefix, "xml") && strcmp(strURI, XML_XML_NAMESPACE)) ||
- (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (prefix, "xmlns") &&
- strcmp (strURI, DOM_XMLNS_NAMESPACE)) ||
- (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (nodep->name, "xmlns"))) {
-
- /* TODO: throw error - find out how to without a return_value
- php_dom_throw_error(NAMESPACE_ERR, &return_value TSRMLS_CC); */
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Namespace");
- return FAILURE;
- }
- ns = xmlNewNs(NULL, nodep->ns->href, (xmlChar *)prefix);
- if (nodep->doc != NULL) {
- doc = nodep->doc;
- if (doc->oldNs == NULL) {
- doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- memset(doc->oldNs, 0, sizeof(xmlNs));
- doc->oldNs->type = XML_LOCAL_NAMESPACE;
- doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE);
- doc->oldNs->prefix = xmlStrdup((const xmlChar *)"xml");
+ if (nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) {
+ strURI = (char *) nodep->ns->href;
+ if (strURI == NULL ||
+ (!strcmp (prefix, "xml") && strcmp(strURI, XML_XML_NAMESPACE)) ||
+ (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (prefix, "xmlns") &&
+ strcmp (strURI, DOM_XMLNS_NAMESPACE)) ||
+ (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (nodep->name, "xmlns"))) {
+
+ /* TODO: throw error - find out how to without a return_value
+ php_dom_throw_error(NAMESPACE_ERR, &return_value TSRMLS_CC); */
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Namespace");
+ return FAILURE;
}
-
- curns = doc->oldNs;
- while (curns->next != NULL) {
- curns = curns->next;
+ ns = xmlNewNs(NULL, nodep->ns->href, (xmlChar *)prefix);
+ if (nodep->doc != NULL) {
+ doc = nodep->doc;
+ if (doc->oldNs == NULL) {
+ doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
+ memset(doc->oldNs, 0, sizeof(xmlNs));
+ doc->oldNs->type = XML_LOCAL_NAMESPACE;
+ doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE);
+ doc->oldNs->prefix = xmlStrdup((const xmlChar *)"xml");
+ }
+
+ curns = doc->oldNs;
+ while (curns->next != NULL) {
+ curns = curns->next;
+ }
+ curns->next = ns;
}
- curns->next = ns;
- }
- nodep->ns = curns;
+ nodep->ns = curns;
+ }
break;
default:
break;
zval *id, *node, *rv = NULL;
xmlNodePtr child, nodep, new_child = NULL;
dom_object *intern, *childobj;
+ xmlNsPtr nsptr;
int ret;
DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
RETURN_FALSE;
}
+ if (new_child->nsDef != NULL && new_child->type == XML_ELEMENT_NODE && new_child->nsDef->href != NULL) {
+ if((nsptr = xmlSearchNsByHref(nodep->doc, new_child->parent, new_child->nsDef->href)) &&
+ (new_child->nsDef->prefix == NULL || xmlStrEqual(nsptr->prefix, new_child->nsDef->prefix))) {
+ dom_set_old_ns(nodep->doc, new_child->ns);
+ new_child->nsDef = NULL;
+ new_child->ns = nsptr;
+ }
+ }
+
DOM_RET_OBJ(rv, new_child, &ret, intern);
}
/* }}} end dom_node_append_child */
*/
PHP_FUNCTION(dom_node_lookup_prefix)
{
- DOM_NOT_IMPLEMENTED();
+ zval *id;
+ xmlNodePtr nodep, lookupp = NULL;
+ dom_object *intern;
+ xmlNsPtr nsptr;
+ int uri_len = 0;
+ char *uri;
+
+ DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &uri_len) == FAILURE) {
+ return;
+ }
+
+ if (uri_len > 0) {
+ switch (nodep->type) {
+ case XML_ELEMENT_NODE:
+ lookupp = nodep;
+ break;
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ lookupp = xmlDocGetRootElement((xmlDocPtr) nodep);
+ break;
+ case XML_ENTITY_NODE :
+ case XML_NOTATION_NODE:
+ case XML_DOCUMENT_FRAG_NODE:
+ case XML_DOCUMENT_TYPE_NODE:
+ case XML_DTD_NODE:
+ RETURN_NULL();
+ break;
+ default:
+ lookupp = nodep->parent;
+ }
+
+ if (lookupp != NULL && (nsptr = xmlSearchNsByHref(lookupp->doc, lookupp, uri))) {
+ if (nsptr->prefix != NULL) {
+ RETURN_STRING((char *) nsptr->prefix, 1);
+ }
+ }
+ }
+
+ RETURN_NULL();
}
/* }}} end dom_node_lookup_prefix */
*/
PHP_FUNCTION(dom_node_lookup_namespace_uri)
{
- DOM_NOT_IMPLEMENTED();
+ zval *id;
+ xmlNodePtr nodep;
+ dom_object *intern;
+ xmlNsPtr nsptr;
+ int prefix_len = 0;
+ char *prefix;
+
+ DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &prefix, &prefix_len) == FAILURE) {
+ return;
+ }
+
+ if (prefix_len > 0) {
+ nsptr = xmlSearchNs(nodep->doc, nodep, prefix);
+ if (nsptr && nsptr->href != NULL) {
+ RETURN_STRING((char *) nsptr->href, 1);
+ }
+ }
+
+ RETURN_NULL();
}
/* }}} end dom_node_lookup_namespace_uri */
uncomment the following line, this will tell you the amount of not freed memory
and the total used memory into apaches error_log */
/* xmlMemoryDump();*/
-
+xmlMemoryDump();
return SUCCESS;
}
}
/* }}} end dom_set_old_ns */
+int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, int name_len) {
+ int errorcode = 0;
-/* {{{ xmlNsPtr dom_get_ns(char *uri, char *qName, int uri_len, int qName_len, int *errorcode, char *localname) */
-xmlNsPtr dom_get_ns(char *uri, char *qName, int uri_len, int qName_len, int *errorcode, char **localname) {
- xmlNsPtr nsptr = NULL;
- xmlURIPtr uristruct;
- char *prefix = NULL;
+ if (uri_len > 0 && name_len > 0) {
+ *localname = xmlSplitQName2(qname, (xmlChar **) prefix);
+ if (*localname == NULL) {
+ *localname = xmlStrdup(qname);
+ }
+ if (*localname == NULL || (xmlStrchr(*localname, (xmlChar) ':') != NULL)) {
+ errorcode = NAMESPACE_ERR;
+ }
+ } else {
+ errorcode = NAMESPACE_ERR;
+ }
- *localname = NULL;
- *errorcode = 0;
+ return errorcode;
+}
- if (uri_len > 0 || qName_len > 0) {
- if (qName_len == 0 && uri_len > 0) {
- *errorcode = NAMESPACE_ERR;
- return nsptr;
- }
- if (qName_len > 0 && *errorcode == 0) {
- uristruct = xmlParseURI(qName);
- if (uristruct->opaque != NULL) {
- prefix = xmlStrdup(uristruct->scheme);
- *localname = xmlStrdup(uristruct->opaque);
- if (xmlStrchr(*localname, (xmlChar) ':') != NULL) {
- *errorcode = NAMESPACE_ERR;
- } else if (!strcmp (prefix, "xml") && strcmp(uri, XML_XML_NAMESPACE)) {
- *errorcode = NAMESPACE_ERR;
- }
- }
+/* {{{ xmlNsPtr dom_get_ns(xmlNodePtr nodep, char *uri, int *errorcode, char *prefix) */
+xmlNsPtr dom_get_ns(xmlNodePtr nodep, char *uri, int *errorcode, char *prefix) {
+ xmlNsPtr nsptr = NULL;
- /* TODO: Test that localname has no invalid chars
- php_dom_throw_error(INVALID_CHARACTER_ERR, TSRMLS_CC);
- */
+ *errorcode = 0;
- xmlFreeURI(uristruct);
-
- if (*errorcode == 0) {
- if (uri_len > 0 && prefix == NULL) {
- *errorcode = NAMESPACE_ERR;
- } else if (*localname != NULL) {
- nsptr = xmlNewNs(NULL, uri, prefix);
- }
- }
- }
+ if (! (prefix && !strcmp (prefix, "xml") && strcmp(uri, XML_XML_NAMESPACE))) {
+ nsptr = xmlNewNs(nodep, uri, prefix);
}
- if (prefix != NULL) {
- xmlFree(prefix);
+ if (nsptr == NULL) {
+ *errorcode = NAMESPACE_ERR;
}
return nsptr;
int decrement_node_ptr(dom_object *object TSRMLS_DC);
int increment_document_reference(dom_object *object, xmlDocPtr docp TSRMLS_DC);
int decrement_document_reference(dom_object *object TSRMLS_DC);
-xmlNsPtr dom_get_ns(char *uri, char *qName, int uri_len, int qName_len, int *errorcode, char **localname);
+int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, int name_len);
+xmlNsPtr dom_get_ns(xmlNodePtr node, char *uri, int *errorcode, char *prefix);
void dom_set_old_ns(xmlDoc *doc, xmlNs *ns);
xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName);
void dom_normalize (xmlNodePtr nodep TSRMLS_DC);