aboutsummaryrefslogtreecommitdiffstats
path: root/tree.c
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>1999-12-21 15:35:29 +0000
committerDaniel Veillard <veillard@src.gnome.org>1999-12-21 15:35:29 +0000
commit5cb5ab8d94a0715ba600b01377cf57531cc97f73 (patch)
tree85cef5e55b46544c46ce3c6bbf8b28a93ea1900e /tree.c
parentf600e2537f838e9806e80572e8e62abc5ff05d98 (diff)
downloadandroid_external_libxml2-5cb5ab8d94a0715ba600b01377cf57531cc97f73.tar.gz
android_external_libxml2-5cb5ab8d94a0715ba600b01377cf57531cc97f73.tar.bz2
android_external_libxml2-5cb5ab8d94a0715ba600b01377cf57531cc97f73.zip
- 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
Diffstat (limited to 'tree.c')
-rw-r--r--tree.c236
1 files changed, 224 insertions, 12 deletions
diff --git a/tree.c b/tree.c
index 86dd6b34..83bed92b 100644
--- a/tree.c
+++ b/tree.c
@@ -1578,12 +1578,85 @@ xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
}
/**
+ * 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 *
@@ -2180,16 +2300,66 @@ xmlDocGetRootElement(xmlDocPtr doc) {
}
/**
+ * 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);
}
@@ -2217,6 +2387,39 @@ xmlNodeGetLang(xmlNodePtr cur) {
}
/**
+ * 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
* @cur: the node being checked
@@ -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);