]> granicus.if.org Git - php/commitdiff
Fix broken Namespace support, use libxml2 namespace methods instead of
authorChristian Stocker <chregu@php.net>
Sun, 22 Feb 2004 17:51:01 +0000 (17:51 +0000)
committerChristian Stocker <chregu@php.net>
Sun, 22 Feb 2004 17:51:01 +0000 (17:51 +0000)
homebrown solution:
- default namespaces are recognized
- different namespaces with same prefix in different nodes are treated correctly
- libxml2 parser warnings are not errors anymore

ext/xml/compat.c
ext/xml/expat_compat.h

index d3133678af338db264cdb42c761df58ffff361c2..8c5de13a2cdc5ea1561096879897a5c43f461577 100644 (file)
@@ -33,119 +33,17 @@ typedef struct _php_xml_ns {
        ((__ns) != NULL && strlen(__ns) == 5 && *(__ns) == 'x' && *((__ns)+1) == 'm' && \
         *((__ns)+2) == 'l' && *((__ns)+3) == 'n' && *((__ns)+4) == 's')
 
-static void
-_find_namespace_decl(XML_Parser parser, const xmlChar *tagname, const xmlChar **attr)
-{
-       xmlChar **attr_p = (xmlChar **) attr;
-       xmlChar  *name;
-       xmlChar  *value;
-       xmlChar  *partial;
-       xmlChar  *namespace;
-       php_xml_ns *cur_ns_scope = NULL;
-       php_xml_ns *exist_ns_scope;
-       xmlNsPtr nsptr, curnsptr;
-
-       exist_ns_scope = xmlHashLookup(parser->_reverse_ns_map, tagname);
-
-       if (exist_ns_scope) {
-               while (exist_ns_scope->next != NULL)
-                       exist_ns_scope = exist_ns_scope->next;
-       }
-
-       while (attr_p && *attr_p) {
-               name = attr_p[0];
-               value = xmlStrdup(attr_p[1]);
-
-               partial = xmlSplitQName(parser->parser, name, &namespace);
-
-               if (IS_NS_DECL(namespace)) {
-
-                       if (parser->h_start_ns) {
-                               parser->h_start_ns(parser->user, partial, (const XML_Char *) value);
-                       }
-                       if (xmlHashLookup(parser->_ns_map, partial) == NULL) {
-                               xmlHashAddEntry(parser->_ns_map, partial, value);
-                       } else {
-                               xmlFree(value);
-                       }
-
-                       nsptr = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
-
-                       if (nsptr) {
-                               memset(nsptr, 0, sizeof(xmlNs));
-                               nsptr->type = XML_LOCAL_NAMESPACE;
-
-                               if (value != NULL)
-                                       nsptr->href = xmlStrdup(value); 
-                               if (partial != NULL)
-                                       nsptr->prefix = xmlStrdup(partial);
-
-                               if (cur_ns_scope == NULL) {
-                                       cur_ns_scope = emalloc(sizeof(php_xml_ns));
-                                       cur_ns_scope->next = NULL;
-                                       cur_ns_scope->prev = NULL;
-                                       cur_ns_scope->nsptr = nsptr;
-                                       cur_ns_scope->ref_count = 0;
-
-                                       if (exist_ns_scope) {
-                                               exist_ns_scope->next = cur_ns_scope;
-                                               cur_ns_scope->prev = exist_ns_scope;
-                                       } else {
-                                               xmlHashAddEntry(parser->_reverse_ns_map, tagname, cur_ns_scope);
-                                       }
-
-                                       exist_ns_scope = cur_ns_scope;
-                               } else {
-                                       curnsptr = cur_ns_scope->nsptr;
-                                       while (curnsptr->next != NULL) {
-                                               curnsptr = curnsptr->next;
-                                       }
-                                       curnsptr->next = nsptr;
-                               }
-                       }
-
-               } else {
-                       xmlFree(value);
-               }
-
-               xmlFree(partial);
-               if (namespace != NULL) {
-                       xmlFree(namespace);
-               }
-
-               attr_p += 2;
-       }
-
-       if (exist_ns_scope) {
-               exist_ns_scope->ref_count++;
-       }
-}
-
 static void 
-_qualify_namespace(XML_Parser parser, const xmlChar *name, xmlChar **qualified)
+_qualify_namespace(XML_Parser parser, const xmlChar *name, const xmlChar *URI, xmlChar **qualified)
 {
-       xmlChar *partial;
-       xmlChar *namespace;
-               
-       partial = xmlSplitQName(parser->parser, name, &namespace);
-       if (namespace) {
-               xmlChar *nsvalue;
-
-               nsvalue = xmlHashLookup(parser->_ns_map, namespace);
-               if (nsvalue) {
+       if (URI) {
                        /* Use libxml functions otherwise its memory deallocation is screwed up */
-                       *qualified = xmlStrdup(nsvalue);
+                       *qualified = xmlStrdup(URI);
                        *qualified = xmlStrncat(*qualified, parser->_ns_seperator, 1);
-                       *qualified = xmlStrncat(*qualified, partial, strlen(partial));
-               } else {
-                       *qualified = xmlStrdup(name);
-               }
-               xmlFree(namespace);
+                       *qualified = xmlStrncat(*qualified, name, strlen(name));
        } else {
                *qualified = xmlStrdup(name);
        }
-       
-       xmlFree(partial);
 }
 
 static void
@@ -157,14 +55,24 @@ _start_element_handler(void *user, const xmlChar *name, const xmlChar **attribut
        if (parser->h_start_element == NULL) {
                return;
        }
-       
-       if (parser->use_namespace) {
-               _find_namespace_decl(parser, name, attributes);
-               _qualify_namespace(parser, name, &qualified_name);
-       } else {
-               qualified_name = xmlStrdup(name);
-       }
 
+       qualified_name = xmlStrdup(name);
+
+       parser->h_start_element(parser->user, (const XML_Char *) qualified_name, (const XML_Char **) attributes);
+
+       xmlFree(qualified_name);
+}
+
+static void
+_start_element_handler_ns(void *user, const xmlChar *name, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, const xmlChar ** attributes)
+{
+       XML_Parser  parser = (XML_Parser) user;
+       xmlChar    *qualified_name = NULL;
+
+       if (parser->h_start_element == NULL) {
+               return;
+       }
+       _qualify_namespace(parser, name, URI, &qualified_name);
        parser->h_start_element(parser->user, (const XML_Char *) qualified_name, (const XML_Char **) attributes);
 
        xmlFree(qualified_name);
@@ -189,41 +97,27 @@ _end_element_handler(void *user, const xmlChar *name)
                return;
        }
        
-       if (parser->use_namespace) {
-               _qualify_namespace(parser, name, &qualified_name);
-       } else {
-               qualified_name = xmlStrdup(name);
-       }
+       qualified_name = xmlStrdup(name);
 
        parser->h_end_element(parser->user, (const XML_Char *) qualified_name);
 
-       if (parser->use_namespace) {
-               int                     tag_counter;
-               php_xml_ns *cur_ns_scope, *prev_ns_scope;
-               xmlNsPtr nsptr;
-
-               cur_ns_scope = xmlHashLookup(parser->_reverse_ns_map, name);
-               if (cur_ns_scope) {
-                       while (cur_ns_scope->next != NULL) {
-                               cur_ns_scope = cur_ns_scope->next;
-                       }
-                       tag_counter = --cur_ns_scope->ref_count;
-                       if (tag_counter == 0) {
-                               nsptr = cur_ns_scope->nsptr;
-                               if (nsptr && parser->h_end_ns) {
-                                       _namespace_handler(parser, nsptr);
-                               }
-                               xmlFreeNsList(nsptr);
-                               cur_ns_scope->nsptr = NULL;
-                               prev_ns_scope = cur_ns_scope->prev;
-                               if (prev_ns_scope != NULL) {
-                                       efree(cur_ns_scope);
-                                       prev_ns_scope->next = NULL;
-                               }
-                       }
-               }
+       xmlFree(qualified_name);
+}
+
+static void
+_end_element_handler_ns(void *user, const xmlChar *name, const xmlChar * prefix, const xmlChar *URI)
+{
+       xmlChar    *qualified_name;
+       XML_Parser  parser = (XML_Parser) user;
+
+       if (parser->h_end_element == NULL) {
+               return;
        }
 
+       _qualify_namespace(parser, name, URI,  &qualified_name);
+
+       parser->h_end_element(parser->user, (const XML_Char *) qualified_name);
+
        xmlFree(qualified_name);
 }
 
@@ -347,7 +241,7 @@ _external_entity_ref_handler(void *user, const xmlChar *names, int type, const x
 
 static xmlSAXHandler 
 php_xml_compat_handlers = {
-    NULL, /* internalSubset */
+       NULL, /* internalSubset */
        NULL, /* isStandalone */
        NULL, /* hasInternalSubset */
        NULL, /* hasExternalSubset */
@@ -361,8 +255,8 @@ php_xml_compat_handlers = {
        NULL, /* setDocumentLocator */
        NULL, /* startDocument */
        NULL, /* endDocument */
-       _start_element_handler,
-       _end_element_handler,
+       _start_element_handler, /* startElement */
+       _end_element_handler, /* endElement */
        NULL, /* reference */
        _cdata_handler,
        NULL, /* ignorableWhitespace */
@@ -374,7 +268,12 @@ php_xml_compat_handlers = {
        NULL,  /* getParameterEntity */
        _cdata_handler, /* cdataBlock */
        NULL, /* externalSubset */
-       1
+       1,
+       NULL,
+       _start_element_handler_ns,
+       _end_element_handler_ns,
+       NULL
+       
 };
 
 PHPAPI XML_Parser 
@@ -415,8 +314,7 @@ XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *m
        parser->parser->replaceEntities = 1;
        if (sep != NULL) {
                parser->use_namespace = 1;
-               parser->_ns_map = xmlHashCreate(10);
-               parser->_reverse_ns_map = xmlHashCreate(10);
+               parser->parser->sax2 = 1;
                parser->_ns_seperator = xmlStrdup(sep);
        }
        return parser;
@@ -498,7 +396,15 @@ XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler en
 PHPAPI int
 XML_Parse(XML_Parser parser, const XML_Char *data, int data_len, int is_final)
 {
-       return !xmlParseChunk(parser->parser, data, data_len, is_final);
+       int error;
+       error = xmlParseChunk(parser->parser, data, data_len, is_final);
+       if (!error) {
+               return 1;
+       } else if (parser->parser->lastError.level > XML_ERR_WARNING ){
+               return 0;
+       } else {
+               return 1;
+       }
 }
 
 PHPAPI int
@@ -603,7 +509,14 @@ const XML_Char *error_mapping[] = {
     "Invalid URI",
     "XML_ERR_URI_FRAGMENT",
     "XML_WAR_CATALOG_PI",
-    "XML_ERR_NO_DTD"
+    "XML_ERR_NO_DTD",
+    "XML_ERR_CONDSEC_INVALID_KEYWORD", /* 95 */
+    "XML_ERR_VERSION_MISSING", /* 96 */
+    "XML_WAR_UNKNOWN_VERSION", /* 97 */
+    "XML_WAR_LANG_VALUE", /* 98 */
+    "XML_WAR_NS_URI", /* 99 */
+    "XML_WAR_NS_URI_RELATIVE", /* 100 */
+    "XML_ERR_MISSING_ENCODING" /* 101 */
 };
 
 PHPAPI const XML_Char *
@@ -648,35 +561,10 @@ PHPAPI const XML_Char *XML_ExpatVersion(void)
        return "1.0";
 }
 
-static void
-_free_ns_name(void *ptr, xmlChar *name)
-{
-       xmlFree(ptr);
-}
-
-static void
-_free_ns_pointer(void *ptr, xmlChar *name)
-{
-       php_xml_ns *cur_ns_scope;
-
-       /* Child scopes should already be removed, but in the event 
-       of malformed xml, they may still be resident and need to be cleaned */
-       cur_ns_scope = ((php_xml_ns *) ptr)->next;
-       if (cur_ns_scope != NULL) {
-               _free_ns_pointer(cur_ns_scope, NULL);
-       }
-
-       xmlFreeNsList(((php_xml_ns *) ptr)->nsptr);
-
-       efree(ptr);
-}
-
 PHPAPI void
 XML_ParserFree(XML_Parser parser)
 {
        if (parser->use_namespace) {
-               xmlHashFree(parser->_ns_map,         _free_ns_name);
-               xmlHashFree(parser->_reverse_ns_map, _free_ns_pointer);
                if (parser->_ns_seperator) {
                        xmlFree(parser->_ns_seperator);
                }
index 1862bc5907b5205380801319e5e21da183637c1c..a13c900041239a94865e05e2545f9c44a31ede93 100644 (file)
@@ -54,8 +54,6 @@ typedef struct _XML_Memory_Handling_Suite {
 typedef struct _XML_Parser {
        int use_namespace;
 
-       xmlHashTablePtr _ns_map;
-       xmlHashTablePtr _reverse_ns_map;
        xmlChar *_ns_seperator;
 
        void *user;