diff --git a/xmlreader.c b/xmlreader.c index 3fd9aa4c..6ae6e922 100644 --- a/xmlreader.c +++ b/xmlreader.c @@ -278,6 +278,59 @@ xmlTextReaderRemoveID(xmlDocPtr doc, xmlAttrPtr attr) { return(0); } +/** + * xmlTextReaderWalkRemoveRef: + * @data: Contents of current link + * @user: Value supplied by the user + * + * Returns 0 to abort the walk or 1 to continue + */ +static int +xmlTextReaderWalkRemoveRef(const void *data, void *user) +{ + xmlRefPtr ref = (xmlRefPtr)data; + xmlAttrPtr attr = (xmlAttrPtr)user; + + if (ref->attr == attr) { /* Matched: remove and terminate walk */ + ref->name = xmlStrdup(attr->name); + ref->attr = NULL; + return 0; + } + return 1; +} + +/** + * xmlTextReaderRemoveRef: + * @doc: the document + * @attr: the attribute + * + * Remove the given attribute from the Ref table maintained internally. + * + * Returns -1 if the lookup failed and 0 otherwise + */ +static int +xmlTextReaderRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) { + xmlListPtr ref_list; + xmlRefTablePtr table; + xmlChar *ID; + + if (doc == NULL) return(-1); + if (attr == NULL) return(-1); + table = (xmlRefTablePtr) doc->refs; + if (table == NULL) + return(-1); + + ID = xmlNodeListGetString(doc, attr->children, 1); + if (ID == NULL) + return(-1); + ref_list = xmlHashLookup(table, ID); + xmlFree(ID); + if(ref_list == NULL) + return (-1); + xmlListWalk(ref_list, xmlTextReaderWalkRemoveRef, attr); + return(0); +} + /** * xmlTextReaderFreeProp: * @reader: the xmlTextReaderPtr used @@ -304,6 +357,8 @@ xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) { (cur->parent->doc->extSubset != NULL))) { if (xmlIsID(cur->parent->doc, cur->parent, cur)) xmlTextReaderRemoveID(cur->parent->doc, cur); + if (xmlIsRef(cur->parent->doc, cur->parent, cur)) + xmlTextReaderRemoveRef(cur->parent->doc, cur); } if (cur->children != NULL) xmlTextReaderFreeNodeList(reader, cur->children);