📄 tree.c
字号:
DICT_FREE(cur->ExternalID) /* TODO !!! */ if (cur->notations != NULL) xmlFreeNotationTable((xmlNotationTablePtr) cur->notations); if (cur->elements != NULL) xmlFreeElementTable((xmlElementTablePtr) cur->elements); if (cur->attributes != NULL) xmlFreeAttributeTable((xmlAttributeTablePtr) cur->attributes); if (cur->entities != NULL) xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities); if (cur->pentities != NULL) xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->pentities); xmlFree(cur);}/** * xmlNewDoc: * @version: xmlChar string giving the version of XML "1.0" * * Creates a new XML document * * Returns a new document */xmlDocPtrxmlNewDoc(const xmlChar *version) { xmlDocPtr cur; if (version == NULL) version = (const xmlChar *) "1.0"; /* * Allocate a new document and fill the fields. */ cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc)); if (cur == NULL) { xmlTreeErrMemory("building doc"); return(NULL); } memset(cur, 0, sizeof(xmlDoc)); cur->type = XML_DOCUMENT_NODE; cur->version = xmlStrdup(version); if (cur->version == NULL) { xmlTreeErrMemory("building doc"); xmlFree(cur); return(NULL); } cur->standalone = -1; cur->compression = -1; /* not initialized */ cur->doc = cur; /* * The in memory encoding is always UTF8 * This field will never change and would * be obsolete if not for binary compatibility. */ cur->charset = XML_CHAR_ENCODING_UTF8; if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) xmlRegisterNodeDefaultValue((xmlNodePtr)cur); return(cur);}/** * xmlFreeDoc: * @cur: pointer to the document * * Free up all the structures used by a document, tree included. */voidxmlFreeDoc(xmlDocPtr cur) { xmlDtdPtr extSubset, intSubset; xmlDictPtr dict = NULL; if (cur == NULL) {#ifdef DEBUG_TREE xmlGenericError(xmlGenericErrorContext, "xmlFreeDoc : document == NULL\n");#endif return; }#ifdef LIBXML_DEBUG_RUNTIME xmlDebugCheckDocument(stderr, cur);#endif if (cur != NULL) dict = cur->dict; if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue)) xmlDeregisterNodeDefaultValue((xmlNodePtr)cur); /* * Do this before freeing the children list to avoid ID lookups */ if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids); cur->ids = NULL; if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs); cur->refs = NULL; extSubset = cur->extSubset; intSubset = cur->intSubset; if (intSubset == extSubset) extSubset = NULL; if (extSubset != NULL) { xmlUnlinkNode((xmlNodePtr) cur->extSubset); cur->extSubset = NULL; xmlFreeDtd(extSubset); } if (intSubset != NULL) { xmlUnlinkNode((xmlNodePtr) cur->intSubset); cur->intSubset = NULL; xmlFreeDtd(intSubset); } if (cur->children != NULL) xmlFreeNodeList(cur->children); if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs); DICT_FREE(cur->version) DICT_FREE(cur->name) DICT_FREE(cur->encoding) DICT_FREE(cur->URL) xmlFree(cur); if (dict) xmlDictFree(dict);}/** * xmlStringLenGetNodeList: * @doc: the document * @value: the value of the text * @len: the length of the string value * * Parse the value string and build the node list associated. Should * produce a flat tree with only TEXTs and ENTITY_REFs. * Returns a pointer to the first child */xmlNodePtrxmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) { xmlNodePtr ret = NULL, last = NULL; xmlNodePtr node; xmlChar *val; const xmlChar *cur = value, *end = cur + len; const xmlChar *q; xmlEntityPtr ent; if (value == NULL) return(NULL); q = cur; while ((cur < end) && (*cur != 0)) { if (cur[0] == '&') { int charval = 0; xmlChar tmp; /* * Save the current text. */ if (cur != q) { if ((last != NULL) && (last->type == XML_TEXT_NODE)) { xmlNodeAddContentLen(last, q, cur - q); } else { node = xmlNewDocTextLen(doc, q, cur - q); if (node == NULL) return(ret); if (last == NULL) last = ret = node; else { last->next = node; node->prev = last; last = node; } } } q = cur; if ((cur + 2 < end) && (cur[1] == '#') && (cur[2] == 'x')) { cur += 3; if (cur < end) tmp = *cur; else tmp = 0; while (tmp != ';') { /* Non input consuming loop */ if ((tmp >= '0') && (tmp <= '9')) charval = charval * 16 + (tmp - '0'); else if ((tmp >= 'a') && (tmp <= 'f')) charval = charval * 16 + (tmp - 'a') + 10; else if ((tmp >= 'A') && (tmp <= 'F')) charval = charval * 16 + (tmp - 'A') + 10; else { xmlTreeErr(XML_TREE_INVALID_HEX, (xmlNodePtr) doc, NULL); charval = 0; break; } cur++; if (cur < end) tmp = *cur; else tmp = 0; } if (tmp == ';') cur++; q = cur; } else if ((cur + 1 < end) && (cur[1] == '#')) { cur += 2; if (cur < end) tmp = *cur; else tmp = 0; while (tmp != ';') { /* Non input consuming loops */ if ((tmp >= '0') && (tmp <= '9')) charval = charval * 10 + (tmp - '0'); else { xmlTreeErr(XML_TREE_INVALID_DEC, (xmlNodePtr) doc, NULL); charval = 0; break; } cur++; if (cur < end) tmp = *cur; else tmp = 0; } if (tmp == ';') cur++; q = cur; } else { /* * Read the entity string */ cur++; q = cur; while ((cur < end) && (*cur != 0) && (*cur != ';')) cur++; if ((cur >= end) || (*cur == 0)) { xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY, (xmlNodePtr) doc, (const char *) q); return(ret); } if (cur != q) { /* * Predefined entities don't generate nodes */ val = xmlStrndup(q, cur - q); ent = xmlGetDocEntity(doc, val); if ((ent != NULL) && (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) { if (last == NULL) { node = xmlNewDocText(doc, ent->content); last = ret = node; } else if (last->type != XML_TEXT_NODE) { node = xmlNewDocText(doc, ent->content); last = xmlAddNextSibling(last, node); } else xmlNodeAddContent(last, ent->content); } else { /* * Create a new REFERENCE_REF node */ node = xmlNewReference(doc, val); if (node == NULL) { if (val != NULL) xmlFree(val); return(ret); } else if ((ent != NULL) && (ent->children == NULL)) { xmlNodePtr temp; ent->children = xmlStringGetNodeList(doc, (const xmlChar*)node->content); ent->owner = 1; temp = ent->children; while (temp) { temp->parent = (xmlNodePtr)ent; ent->last = temp; temp = temp->next; } } if (last == NULL) { last = ret = node; } else { last = xmlAddNextSibling(last, node); } } xmlFree(val); } cur++; q = cur; } if (charval != 0) { xmlChar buf[10]; int l; l = xmlCopyCharMultiByte(buf, charval); buf[l] = 0; node = xmlNewDocText(doc, buf); if (node != NULL) { if (last == NULL) { last = ret = node; } else { last = xmlAddNextSibling(last, node); } } charval = 0; } } else cur++; } if ((cur != q) || (ret == NULL)) { /* * Handle the last piece of text. */ if ((last != NULL) && (last->type == XML_TEXT_NODE)) { xmlNodeAddContentLen(last, q, cur - q); } else { node = xmlNewDocTextLen(doc, q, cur - q); if (node == NULL) return(ret); if (last == NULL) { last = ret = node; } else { last = xmlAddNextSibling(last, node); } } } return(ret);}/** * xmlStringGetNodeList: * @doc: the document * @value: the value of the attribute * * Parse the value string and build the node list associated. Should * produce a flat tree with only TEXTs and ENTITY_REFs. * Returns a pointer to the first child */xmlNodePtrxmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) { xmlNodePtr ret = NULL, last = NULL; xmlNodePtr node; xmlChar *val; const xmlChar *cur = value; const xmlChar *q; xmlEntityPtr ent; if (value == NULL) return(NULL); q = cur; while (*cur != 0) { if (cur[0] == '&') { int charval = 0; xmlChar tmp; /* * Save the current text. */ if (cur != q) { if ((last != NULL) && (last->type == XML_TEXT_NODE)) { xmlNodeAddContentLen(last, q, cur - q); } else { node = xmlNewDocTextLen(doc, q, cur - q); if (node == NULL) return(ret); if (last == NULL) last = ret = node; else { last->next = node; node->prev = last; last = node; } } } q = cur; if ((cur[1] == '#') && (cur[2] == 'x')) { cur += 3; tmp = *cur; while (tmp != ';') { /* Non input consuming loop */ if ((tmp >= '0') && (tmp <= '9')) charval = charval * 16 + (tmp - '0'); else if ((tmp >= 'a') && (tmp <= 'f')) charval = charval * 16 + (tmp - 'a') + 10; else if ((tmp >= 'A') && (tmp <= 'F')) charval = charval * 16 + (tmp - 'A') + 10; else { xmlTreeErr(XML_TREE_INVALID_HEX, (xmlNodePtr) doc, NULL); charval = 0; break; } cur++; tmp = *cur; } if (tmp == ';') cur++; q = cur; } else if (cur[1] == '#') { cur += 2; tmp = *cur; while (tmp != ';') { /* Non input consuming loops */ if ((tmp >= '0') && (tmp <= '9')) charval = charval * 10 + (tmp - '0'); else { xmlTreeErr(XML_TREE_INVALID_DEC, (xmlNodePtr) doc, NULL); charval = 0; break; } cur++; tmp = *cur; } if (tmp == ';') cur++; q = cur; } else { /* * Read the entity string */ cur++; q = cur; while ((*cur != 0) && (*cur != ';')) cur++; if (*cur == 0) { xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY, (xmlNodePtr) doc, (const char *) q); return(ret); } if (cur != q) { /* * Predefined entities don't generate nodes */ val = xmlStrndup(q, cur - q); ent = xmlGetDocEntity(doc, val); if ((ent != NULL) && (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) { if (last == NULL) { node = xmlNewDocText(doc, ent->content); last = ret = node; } else if (last->type != XML_TEXT_NODE) { node = xmlNewDocText(doc, ent->content); last = xmlAddNextSibling(last, node); } else xmlNodeAddContent(last, ent->content); } else { /* * Create a new REFERENCE_REF node */ node = xmlNewReference(doc, val); if (node == NULL) { if (val != NULL) xmlFree(val); return(ret); } else if ((ent != NULL) && (ent->children == NULL)) { xmlNodePtr temp; ent->children = xmlStringGetNodeList(doc, (const xmlChar*)node->content); ent->owner = 1; temp = ent->children; while (temp) { temp->parent = (xmlNodePtr)ent; temp = temp->next; } } if (last == NULL) { last = ret = node; } else { last = xmlAddNextSibling(last, node); } } xmlFree(val); } cur++; q = cur; } if (charval != 0) { xmlChar buf[10]; int len; len = xmlCopyCharMultiByte(buf, charval); buf[len] = 0; node = xmlNewDocText(doc, buf); if (node != NULL) { if (last == NULL) { last = ret = node; } else { last = xmlAddNextSibling(last, node); } } charval = 0; } } else cur++; } if ((cur != q) || (ret == NULL)) { /* * Handle the last piece of text. */ if ((last != NULL) && (last->type == XML_TEXT_NODE)) { xmlNodeAddContentLen(last, q, cur - q); } else { node = xmlNewDocTextLen(doc, q, cur - q); if (node == NULL) return(ret); if (last == NULL) { last = ret = node; } else { last = xmlAddNextSibling(last, node); } } } return(ret);}/** * xmlNodeListGetString: * @doc: the document * @list: a Node list * @inLine: should we replace entity contents or show their external form * * Build the string equivalent to the text contained in the Node list * made of TEXTs and ENTITY_REFs * * Returns a pointer to the string copy, the caller must free it with xmlFree(). */xmlChar *xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine){ xmlNodePtr node = list; xmlChar *ret = NULL; xmlEntityPtr ent; if (list == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -