1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-30 22:43:14 +03:00

- release 1.8.2 - HTML handling improvement - new tree handling functions

- release 1.8.2
- HTML handling improvement
- new tree handling functions
- default namespace on attribute bug fixed
- libxml use for C++ fixed (for good this time !)
Daniel
This commit is contained in:
Daniel Veillard
1999-12-21 15:35:29 +00:00
parent f600e2537f
commit 5cb5ab8d94
41 changed files with 2680 additions and 2036 deletions

236
tree.c
View File

@ -1577,13 +1577,86 @@ xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
return(cur);
}
/**
* xmlAddNextSibling:
* @cur: the child node
* @elem: the new node
*
* Add a new element @elem as the next siblings of @cur
* If the new element was already inserted in a document it is
* first unlinked from its existing context.
*
* Returns the new element or NULL in case of error.
*/
xmlNodePtr
xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
if (cur == NULL) {
fprintf(stderr, "xmlAddNextSibling : cur == NULL\n");
return(NULL);
}
if (elem == NULL) {
fprintf(stderr, "xmlAddNextSibling : elem == NULL\n");
return(NULL);
}
xmlUnlinkNode(elem);
elem->doc = cur->doc;
elem->parent = cur->parent;
elem->next = cur;
elem->prev = cur->prev;
cur->prev = elem;
if (elem->prev != NULL)
elem->prev->next = elem;
if ((elem->parent != NULL) && (elem->parent->childs == cur))
elem->parent->childs = elem;
return(elem);
}
/**
* xmlAddPrevSibling:
* @cur: the child node
* @elem: the new node
*
* Add a new element @elem as the previous siblings of @cur
* If the new element was already inserted in a document it is
* first unlinked from its existing context.
*
* Returns the new element or NULL in case of error.
*/
xmlNodePtr
xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) {
if (cur == NULL) {
fprintf(stderr, "xmlAddPrevSibling : cur == NULL\n");
return(NULL);
}
if (elem == NULL) {
fprintf(stderr, "xmlAddPrevSibling : elem == NULL\n");
return(NULL);
}
xmlUnlinkNode(elem);
elem->doc = cur->doc;
elem->parent = cur->parent;
elem->prev = cur;
elem->next = cur->next;
cur->next = elem;
if (elem->next != NULL)
elem->next->prev = elem;
if ((elem->parent != NULL) && (elem->parent->last == cur))
elem->parent->last = elem;
return(elem);
}
/**
* xmlAddSibling:
* @cur: the child node
* @elem: the new node
*
* Add a new element to the list of siblings of @cur
* Returns the element or NULL in case of error.
* Add a new element @elem to the list of siblings of @cur
* If the new element was already inserted in a document it is
* first unlinked from its existing context.
*
* Returns the new element or NULL in case of error.
*/
xmlNodePtr
xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
@ -1599,14 +1672,20 @@ xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
return(NULL);
}
if ((cur->doc != NULL) && (elem->doc != NULL) &&
(cur->doc != elem->doc)) {
fprintf(stderr,
"xmlAddSibling: Elements moved to a different document\n");
/*
* Constant time is we can rely on the ->parent->last to find
* the last sibling.
*/
if ((cur->parent != NULL) &&
(cur->parent->childs != NULL) &&
(cur->parent->last != NULL) &&
(cur->parent->last->next == NULL)) {
cur = cur->parent->last;
} else {
while (cur->next != NULL) cur = cur->next;
}
while (cur->next != NULL) cur = cur->next;
xmlUnlinkNode(elem);
if (elem->doc == NULL)
elem->doc = cur->doc; /* the parent may not be linked to a doc ! */
@ -1784,6 +1863,47 @@ xmlUnlinkNode(xmlNodePtr cur) {
cur->parent = NULL;
}
/**
* xmlReplaceNode:
* @old: the old node
* @cur: the node
*
* Unlink the old node from it's current context, prune the new one
* at the same place. If cur was already inserted in a document it is
* first unlinked from its existing context.
*
* Returns the old node
*/
xmlNodePtr
xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
if (old == NULL) {
fprintf(stderr, "xmlReplaceNode : old == NULL\n");
return(NULL);
}
if (cur == NULL) {
xmlUnlinkNode(old);
return(old);
}
xmlUnlinkNode(cur);
cur->doc = old->doc;
cur->parent = old->parent;
cur->next = old->next;
if (cur->next != NULL)
cur->next->prev = cur;
cur->prev = old->prev;
if (cur->prev != NULL)
cur->prev->next = cur;
if (cur->parent != NULL) {
if (cur->parent->childs == old)
cur->parent->childs = cur;
if (cur->parent->last == old)
cur->parent->last = cur;
}
old->next = old->prev = NULL;
old->parent = NULL;
return(old);
}
/************************************************************************
* *
* Copy operations *
@ -2179,17 +2299,67 @@ xmlDocGetRootElement(xmlDocPtr doc) {
return(ret);
}
/**
* xmlDocSetRootElement:
* @doc: the document
* @root: the new document root element
*
* Set the root element of the document (doc->root is a list
* containing possibly comments, PIs, etc ...).
*
* Returns the old root element if any was found
*/
xmlNodePtr
xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
xmlNodePtr old = NULL;
if (doc == NULL) return(NULL);
old = doc->root;
while (old != NULL) {
if (old->type == XML_ELEMENT_NODE)
break;
old = old->next;
}
if (old == NULL) {
if (doc->root == NULL) {
doc->root = root;
} else {
xmlAddSibling(doc->root, root);
}
} else {
xmlReplaceNode(old, root);
}
return(old);
}
/**
* xmlNodeSetLang:
* @cur: the node being changed
* @lang: the langage description
*
* Searches the language of a node, i.e. the values of the xml:lang
* attribute or the one carried by the nearest ancestor.
* Set the language of a node, i.e. the values of the xml:lang
* attribute.
*/
void
xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
/* TODO xmlNodeSetLang check against the production [33] LanguageID */
if (cur == NULL) return;
switch(cur->type) {
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_COMMENT_NODE:
case XML_DOCUMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_NOTATION_NODE:
case XML_HTML_DOCUMENT_NODE:
return;
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
case XML_PI_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
break;
}
xmlSetProp(cur, BAD_CAST "xml:lang", lang);
}
@ -2216,6 +2386,39 @@ xmlNodeGetLang(xmlNodePtr cur) {
return(NULL);
}
/**
* xmlNodeSetName:
* @cur: the node being changed
* @name: the new tag name
*
* Searches the language of a node, i.e. the values of the xml:lang
* attribute or the one carried by the nearest ancestor.
*/
void
xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
if (cur == NULL) return;
if (name == NULL) return;
switch(cur->type) {
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_COMMENT_NODE:
case XML_DOCUMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_NOTATION_NODE:
case XML_HTML_DOCUMENT_NODE:
return;
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
case XML_PI_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
break;
}
if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
cur->name = xmlStrdup(name);
}
/**
* xmlNodeGetBase:
* @doc: the document the node pertains to
@ -2787,8 +2990,17 @@ xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *namespace) {
if (namespace == NULL)
return(xmlGetProp(node, name));
while (prop != NULL) {
/*
* One need to have
* - same attribute names
* - and the attribute carrying that namespace
* or
* no namespace on the attribute and the element carrying it
*/
if ((!xmlStrcmp(prop->name, name)) &&
(prop->ns != NULL) && (!xmlStrcmp(prop->ns->href, namespace))) {
(((prop->ns == NULL) && (node->ns != NULL) &&
(!xmlStrcmp(node->ns->href, namespace))) ||
(prop->ns != NULL) && (!xmlStrcmp(prop->ns->href, namespace)))) {
xmlChar *ret;
ret = xmlNodeListGetString(node->doc, prop->val, 1);