From 54f9a4f5089a974cd773ab285637ea21df01202c Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Sat, 3 Sep 2005 13:28:24 +0000 Subject: fixing a number of issues raised by xml:id but more generally related to * SAX2.c tree.c valid.c: fixing a number of issues raised by xml:id but more generally related to attributes and ID handling, fixes #314358 among other things Daniel --- tree.c | 128 +++++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 82 insertions(+), 46 deletions(-) (limited to 'tree.c') diff --git a/tree.c b/tree.c index 1da8400c..3031d503 100644 --- a/tree.c +++ b/tree.c @@ -297,6 +297,7 @@ xmlSplitQName2(const xmlChar *name, xmlChar **prefix) { * * returns NULL if it is not a Qualified Name, otherwise, update len * with the lenght in byte of the prefix and return a pointer + * to the start of the name without the prefix */ const xmlChar * @@ -1723,80 +1724,87 @@ xmlNodeListGetRawString(xmlDocPtr doc, xmlNodePtr list, int inLine) } #endif /* LIBXML_TREE_ENABLED */ -static xmlAttrPtr xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns, - const xmlChar *name, const xmlChar *value, int eatname) { +static xmlAttrPtr +xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns, + const xmlChar * name, const xmlChar * value, + int eatname) +{ xmlAttrPtr cur; xmlDocPtr doc = NULL; if ((node != NULL) && (node->type != XML_ELEMENT_NODE)) { - if (eatname == 1) - xmlFree((xmlChar *) name); - return(NULL); - } + if (eatname == 1) + xmlFree((xmlChar *) name); + return (NULL); + } /* * Allocate a new property and fill the fields. */ cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr)); if (cur == NULL) { - if (eatname == 1) - xmlFree((xmlChar *) name); - xmlTreeErrMemory("building attribute"); - return(NULL); + if (eatname == 1) + xmlFree((xmlChar *) name); + xmlTreeErrMemory("building attribute"); + return (NULL); } memset(cur, 0, sizeof(xmlAttr)); cur->type = XML_ATTRIBUTE_NODE; - cur->parent = node; + cur->parent = node; if (node != NULL) { - doc = node->doc; - cur->doc = doc; + doc = node->doc; + cur->doc = doc; } - cur->ns = ns; + cur->ns = ns; - if (eatname == 0) { - if ((doc != NULL) && (doc->dict != NULL)) - cur->name = (xmlChar *) xmlDictLookup(doc->dict, name, -1); - else - cur->name = xmlStrdup(name); - } else - cur->name = name; + if (eatname == 0) { + if ((doc != NULL) && (doc->dict != NULL)) + cur->name = (xmlChar *) xmlDictLookup(doc->dict, name, -1); + else + cur->name = xmlStrdup(name); + } else + cur->name = name; if (value != NULL) { - xmlChar *buffer; - xmlNodePtr tmp; - - buffer = xmlEncodeEntitiesReentrant(doc, value); - cur->children = xmlStringGetNodeList(doc, buffer); - cur->last = NULL; - tmp = cur->children; - while (tmp != NULL) { - tmp->parent = (xmlNodePtr) cur; - if (tmp->next == NULL) - cur->last = tmp; - tmp = tmp->next; - } - xmlFree(buffer); - } + xmlChar *buffer; + xmlNodePtr tmp; + + buffer = xmlEncodeEntitiesReentrant(doc, value); + cur->children = xmlStringGetNodeList(doc, buffer); + cur->last = NULL; + tmp = cur->children; + while (tmp != NULL) { + tmp->parent = (xmlNodePtr) cur; + if (tmp->next == NULL) + cur->last = tmp; + tmp = tmp->next; + } + xmlFree(buffer); + } /* * Add it at the end to preserve parsing order ... */ if (node != NULL) { - if (node->properties == NULL) { - node->properties = cur; - } else { - xmlAttrPtr prev = node->properties; + if (node->properties == NULL) { + node->properties = cur; + } else { + xmlAttrPtr prev = node->properties; - while (prev->next != NULL) prev = prev->next; - prev->next = cur; - cur->prev = prev; - } + while (prev->next != NULL) + prev = prev->next; + prev->next = cur; + cur->prev = prev; + } } + if (xmlIsID((node == NULL) ? NULL : node->doc, node, cur) == 1) + xmlAddID(NULL, node->doc, value, cur); + if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) - xmlRegisterNodeDefaultValue((xmlNodePtr)cur); - return(cur); + xmlRegisterNodeDefaultValue((xmlNodePtr) cur); + return (cur); } #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \ @@ -6316,16 +6324,36 @@ xmlAttrPtr xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) { xmlAttrPtr prop; xmlDocPtr doc; + int len; + const xmlChar *nqname; if ((node == NULL) || (name == NULL) || (node->type != XML_ELEMENT_NODE)) return(NULL); + + /* + * handle QNames + */ + nqname = xmlSplitQName3(name, &len); + if (nqname != NULL) { + xmlNsPtr ns; + xmlChar *prefix = xmlStrndup(name, len); + ns = xmlSearchNs(node->doc, node, prefix); + if (prefix != NULL) + xmlFree(prefix); + if (ns != NULL) + return(xmlSetNsProp(node, ns, nqname, value)); + } + doc = node->doc; prop = node->properties; while (prop != NULL) { if ((xmlStrEqual(prop->name, name)) && (prop->ns == NULL)){ xmlNodePtr oldprop = prop->children; + int id = xmlIsID(node->doc, node, prop); + if (id == 1) + xmlRemoveID(node->doc, prop); prop->children = NULL; prop->last = NULL; if (value != NULL) { @@ -6348,6 +6376,8 @@ xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) { } if (oldprop != NULL) xmlFreeNodeList(oldprop); + if (id) + xmlAddID(NULL, node->doc, value, prop); return(prop); } prop = prop->next; @@ -6390,6 +6420,10 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, */ if ((xmlStrEqual(prop->name, name)) && (prop->ns != NULL) && (xmlStrEqual(prop->ns->href, ns->href))) { + int id = xmlIsID(node->doc, node, prop); + + if (id == 1) + xmlRemoveID(node->doc, prop); if (prop->children != NULL) xmlFreeNodeList(prop->children); prop->children = NULL; @@ -6411,6 +6445,8 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, } xmlFree(buffer); } + if (id) + xmlAddID(NULL, node->doc, value, prop); return(prop); } prop = prop->next; -- cgit v1.2.3