📄 tree.c
字号:
if (cur->encoding != NULL) xmlFree((char *) cur->encoding); if (cur->children != NULL) xmlFreeNodeList(cur->children); if (cur->intSubset != NULL) xmlFreeDtd(cur->intSubset); if (cur->extSubset != NULL) xmlFreeDtd(cur->extSubset); if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs); if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids); if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs); if (cur->URL != NULL) xmlFree((char *) cur->URL); memset(cur, -1, sizeof(xmlDoc)); xmlFree(cur);}/** * 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; const xmlChar *q; xmlEntityPtr ent; if (value == NULL) return(NULL); q = cur; while ((*cur != 0) && (cur - value < len)) { if (*cur == '&') { /* * 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; } } } /* * Read the entity string */ cur++; q = cur; while ((*cur != 0) && (cur - value < len) && (*cur != ';')) cur++; if ((*cur == 0) || (cur - value >= len)) {#ifdef DEBUG_TREE fprintf(stderr, "xmlStringLenGetNodeList: unterminated entity %30s\n", q);#endif 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 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); } if (last == NULL) last = ret = node; else { last->next = node; node->prev = last; last = node; } } xmlFree(val); } cur++; q = cur; } else cur++; } if (cur != q) { /* * 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->next = node; node->prev = last; 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 == '&') { /* * 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; } } } /* * Read the entity string */ cur++; q = cur; while ((*cur != 0) && (*cur != ';')) cur++; if (*cur == 0) {#ifdef DEBUG_TREE fprintf(stderr, "xmlStringGetNodeList: unterminated entity %30s\n", q);#endif 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 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); } if (last == NULL) last = ret = node; else { last->next = node; node->prev = last; last = node; } } xmlFree(val); } cur++; q = cur; } else cur++; } if (cur != q) { /* * 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->next = node; node->prev = last; last = node; } } } return(ret);}/** * xmlNodeListGetString: * @doc: the document * @list: a Node list * @inLine: should we replace entity contents or show their external form * * Returns 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 calller must free it. */xmlChar *xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) { xmlNodePtr node = list; xmlChar *ret = NULL; xmlEntityPtr ent; if (list == NULL) return(NULL); while (node != NULL) { if (node->type == XML_TEXT_NODE) { if (inLine) {#ifndef XML_USE_BUFFER_CONTENT ret = xmlStrcat(ret, node->content);#else ret = xmlStrcat(ret, xmlBufferContent(node->content));#endif } else { xmlChar *buffer;#ifndef XML_USE_BUFFER_CONTENT buffer = xmlEncodeEntitiesReentrant(doc, node->content);#else buffer = xmlEncodeEntitiesReentrant(doc, xmlBufferContent(node->content));#endif if (buffer != NULL) { ret = xmlStrcat(ret, buffer); xmlFree(buffer); } } } else if (node->type == XML_ENTITY_REF_NODE) { if (inLine) { ent = xmlGetDocEntity(doc, node->name); if (ent != NULL) ret = xmlStrcat(ret, ent->content); else {#ifndef XML_USE_BUFFER_CONTENT ret = xmlStrcat(ret, node->content);#else ret = xmlStrcat(ret, xmlBufferContent(node->content));#endif } } else { xmlChar buf[2]; buf[0] = '&'; buf[1] = 0; ret = xmlStrncat(ret, buf, 1); ret = xmlStrcat(ret, node->name); buf[0] = ';'; buf[1] = 0; ret = xmlStrncat(ret, buf, 1); } }#if 0 else { fprintf(stderr, "xmlGetNodeListString : invalide node type %d\n", node->type); }#endif node = node->next; } return(ret);}/** * xmlNewProp: * @node: the holding node * @name: the name of the attribute * @value: the value of the attribute * * Create a new property carried by a node. * Returns a pointer to the attribute */xmlAttrPtrxmlNewProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) { xmlAttrPtr cur; if (name == NULL) {#ifdef DEBUG_TREE fprintf(stderr, "xmlNewProp : name == NULL\n");#endif return(NULL); } /* * Allocate a new property and fill the fields. */ cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr)); if (cur == NULL) { fprintf(stderr, "xmlNewProp : malloc failed\n"); return(NULL); } memset(cur, 0, sizeof(xmlAttr)); cur->type = XML_ATTRIBUTE_NODE; cur->parent = node; cur->name = xmlStrdup(name); if (value != NULL) { xmlChar *buffer; xmlNodePtr tmp; buffer = xmlEncodeEntitiesReentrant(node->doc, value); cur->children = xmlStringGetNodeList(node->doc, buffer); 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; while (prev->next != NULL) prev = prev->next; prev->next = cur; cur->prev = prev; } } return(cur);}/** * xmlNewNsProp: * @node: the holding node * @ns: the namespace * @name: the name of the attribute * @value: the value of the attribute * * Create a new property tagged with a namespace and carried by a node. * Returns a pointer to the attribute */xmlAttrPtrxmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, const xmlChar *value) { xmlAttrPtr cur; if (name == NULL) {#ifdef DEBUG_TREE fprintf(stderr, "xmlNewProp : name == NULL\n");#endif return(NULL); } /* * Allocate a new property and fill the fields. */ cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr)); if (cur == NULL) { fprintf(stderr, "xmlNewProp : malloc failed\n"); return(NULL); } memset(cur, 0, sizeof(xmlAttr)); cur->type = XML_ATTRIBUTE_NODE; cur->parent = node; if (node != NULL) cur->doc = node->doc; cur->ns = ns; cur->name = xmlStrdup(name); if (value != NULL) { xmlChar *buffer; xmlNodePtr tmp; buffer = xmlEncodeEntitiesReentrant(node->doc, value); cur->children = xmlStringGetNodeList(node->doc, buffer); 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; while (prev->next != NULL) prev = prev->next; prev->next = cur; cur->prev = prev; } } return(cur);}/** * xmlNewDocProp: * @doc: the document * @name: the name of the attribute * @value: the value of the attribute * * Create a new property carried by a document. * Returns a pointer to the attribute */xmlAttrPtrxmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value) { xmlAttrPtr cur; if (name == NULL) {#ifdef DEBUG_TREE fprintf(stderr, "xmlNewProp : name == NULL\n");#endif return(NULL); } /* * Allocate a new property and fill the fields. */ cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr)); if (cur == NULL) { fprintf(stderr, "xmlNewProp : malloc failed\n"); return(NULL); } memset(cur, 0, sizeof(xmlAttr)); cur->type = XML_ATTRIBUTE_NODE; cur->name = xmlStrdup(name); cur->doc = doc; if (value != NULL) cur->children = xmlStringGetNodeList(doc, value); return(cur);}/** * xmlFreePropList: * @cur: the first property in the list * * Free a property and all its siblings, all the children are freed too. */voidxmlFreePropList(xmlAttrPtr cur) { xmlAttrPtr next; if (cur == NULL) {#ifdef DEBUG_TREE fprintf(stderr, "xmlFreePropList : property == NULL\n");#endif return; } while (cur != NULL) { next = cur->next; xmlFreeProp(cur); cur = next; }}/** * xmlFreeProp: * @cur: an attribute * * Free one attribute, all the content is freed too */voidxmlFreeProp(xmlAttrPtr cur) { if (cur == NULL) {#ifdef DEBUG_TREE fprintf(stderr, "xmlFreeProp : property == NULL\n");#endif return; } /* Check for ID removal -> leading to invalid references ! */ if ((cur->parent != NULL) && (xmlIsID(cur->parent->doc, cur->parent, cur))) xmlRemoveID(cur->parent->doc, cur); if (cur->name != NULL) xmlFree((char *) cur->name); if (cur->children != NULL) xmlFreeNodeList(cur->children); memset(cur, -1, sizeof(xmlAttr)); xmlFree(cur);}/** * xmlRemoveProp: * @cur: an attribute * * Unlink and free one attribute, all the content is freed too * Note this doesn't work for namespace definition attributes
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -