首页 > 代码库 > libxml
libxml
1 /** 2 * section: Tree 3 * synopsis: Navigates a tree to print element names 4 * purpose: Parse a file to a tree, use xmlDocGetRootElement() to 5 * get the root element, then walk the document and print 6 * all the element name in document order. 7 * usage: tree1 filename_or_URL 8 * test: tree1 test2.xml > tree1.tmp && diff tree1.tmp $(srcdir)/tree1.res 9 * author: Dodji Seketeli 10 * copy: see Copyright for the status of this software. 11 */ 12 #include <stdio.h> 13 #include <string.h> 14 #include <libxml/parser.h> 15 #include <libxml/tree.h> 16 17 /* 18 *To compile this file using gcc you can type 19 * gcc `xml2-config --cflags --libs` -o tree1 tree1.c 20 *Run this program 21 * ./tree1 test.xml 22 */ 23 24 static const char* LEVELS[] = {"", " ", " ", " ", " ", " ", " ", " " }; 25 26 static void printTree(xmlNode * a_node, int level); 27 28 /** 29 * print_element_names: 30 * @a_node: the initial xml node to consider. 31 * 32 * 打印所有兄弟节点和子节点的名字. 33 */ 34 static void print_element_names(xmlNode * a_node, const char* msg); 35 36 37 // 根据标签名称获取节点(可以实现更加复杂的逻辑,获取指定节点) 38 static xmlNode *getNode(xmlNode *rootNode, const char* tag, xmlNode **parentNode); 39 40 // 删除当前节点,但是保留子节点 41 static void removeNode(xmlNode *parentNode, xmlNode *nodeToDelete); 42 43 // 用一个父节点包装子节点 44 static void wrapWithNode(xmlNode *parentNode, xmlNode *node, xmlNode *newNode); 45 46 // 增加一个新节点 47 static void appendNewChildNode(xmlNode *parentNode, xmlNode *newNode); 48 49 /** 50 * print_element_names: 51 * @a_node: the initial xml node to consider. 52 * 53 * Prints the names of the all the xml elements 54 * that are siblings or children of a given xml node. 55 */ 56 static int test_removeNode(const char* filepath); 57 58 /** 59 * print_element_names: 60 * @a_node: the initial xml node to consider. 61 * 62 * Prints the names of the all the xml elements 63 * that are siblings or children of a given xml node. 64 */ 65 static int test_wrapWithNode(const char* filepath); 66 67 int main(int argc, char **argv) 68 { 69 if (argc != 2) { 70 printf("error: invalid arguments"); 71 return -1; 72 } 73 74 /* 75 * this initialize the library and check potential ABI mismatches 76 * between the version it was compiled for and the actual shared 77 * library used. 78 */ 79 LIBXML_TEST_VERSION 80 81 printf("test: removeNode:\n"); 82 test_removeNode(argv[1]); 83 84 printf("\n\ntest: wrapWithNode\n"); 85 test_wrapWithNode(argv[1]); 86 87 /* 88 *Free the global variables that may 89 *have been allocated by the parser. 90 */ 91 xmlCleanupParser(); 92 93 return 0; 94 } 95 96 void print_element_names(xmlNode * a_node, const char* msg) 97 { 98 xmlNode *cur_node = NULL; 99 100 if (msg != NULL && strlen(msg) > 0) {101 printf("print: %s\n", msg);102 }103 104 for (cur_node = a_node; cur_node; cur_node = cur_node->next) {105 if (cur_node->type == XML_ELEMENT_NODE) {106 printf("node type: Element, name: %s\n", cur_node->name);107 }108 109 print_element_names(cur_node->children, "");110 }111 }112 113 void printTree(xmlNode * a_node, int level)114 {115 xmlNode *cur_node = NULL;116 117 //printf("%s", LEVELS[level]);118 119 for (cur_node = a_node; cur_node; cur_node = cur_node->next) {120 if (cur_node->type == XML_ELEMENT_NODE) {121 printf("%s%s <%d>\n", LEVELS[level], cur_node->name, cur_node->type);122 printTree(cur_node->children, level + 1);123 } else {124 printf("%s#%s <%d>\n", LEVELS[level], cur_node->name, cur_node->type);125 }126 }127 }128 129 xmlNode *getNode(xmlNode *rootNode, const char* tag, xmlNode **parentNode) {130 xmlNode *cur = rootNode;131 if ((cur->type == XML_ELEMENT_NODE) && (!xmlStrcmp(cur->name, (const xmlChar *)tag))){132 *parentNode = NULL;133 return cur;134 }135 136 *parentNode = cur;137 cur = cur->xmlChildrenNode;138 while (cur != NULL) {139 if ((cur->type == XML_ELEMENT_NODE) && (!xmlStrcmp(cur->name, (const xmlChar *)tag))){140 return cur;141 }142 143 if (cur->type == XML_ELEMENT_NODE) {144 *parentNode = cur;145 }146 cur = cur->next;147 }148 149 return NULL;150 }151 152 // 删除当前节点,但是保留子节点153 void removeNode(xmlNode *parentNode, xmlNode *nodeToDelete) {154 if (nodeToDelete == NULL) {155 printf("error: nodeToDelete is null");156 return;157 }158 159 xmlNodePtr siblingNode = nodeToDelete->next;160 161 while (siblingNode != NULL) {162 if (siblingNode->type == XML_ELEMENT_NODE) {163 printf("debug: found sibling: %s\n", siblingNode->name);164 break;165 }166 167 siblingNode = siblingNode->next;168 }169 170 printf("debug: parentNode: %s, nodeToDelete: %s\n", parentNode->name, nodeToDelete->name);171 printTree(parentNode, 0);172 173 xmlNode *childrenNode = nodeToDelete->children;174 if (childrenNode == NULL) {175 printf("warn: childrenNode is null\n");176 }177 //xmlUnlinkNode(nodeToDelete->children);178 179 xmlNodePtr nextChildNode = NULL;180 181 while (childrenNode != NULL) {182 printf("debug: childrenNode: %s\n", childrenNode->name);183 nextChildNode = childrenNode->next;184 xmlUnlinkNode(childrenNode);185 186 if (siblingNode != NULL) {187 printf("debug: addPreSibling: %s, sibling is %s\n", childrenNode->name, siblingNode->name);188 xmlAddPrevSibling(siblingNode, nextChildNode);189 } else {190 printf("debug: addChild: %s, parent is %s\n", childrenNode->name, parentNode->name);191 printTree(childrenNode, 0);192 xmlAddChild(parentNode, childrenNode);193 }194 195 childrenNode = nextChildNode;196 }197 198 xmlUnlinkNode(nodeToDelete); 199 xmlFreeNode(nodeToDelete);200 }201 202 // 用一个父节点包装子节点203 void wrapWithNode(xmlNode *parentNode, xmlNode *node, xmlNode *newNode) {204 xmlUnlinkNode(node);205 xmlAddChild(newNode, node);206 xmlAddChild(parentNode, newNode);207 }208 209 // 增加一个新节点210 void appendNewChildNode(xmlNode *parentNode, xmlNode *newNode) {211 xmlAddChild(parentNode, newNode);212 }213 214 int test_removeNode(const char* filepath) {215 xmlDoc *doc = NULL;216 xmlNode *root_element = NULL;217 xmlNode *parentNode = NULL;218 xmlNode *curNode = NULL;219 220 /*parse the file and get the DOM */221 doc = xmlReadFile(filepath, NULL, 0);222 223 if (doc == NULL) {224 printf("error: could not parse file %s\n", filepath);225 }226 227 /*Get the root element node */228 root_element = xmlDocGetRootElement(doc);229 230 // 删除节点,但是保留子节点231 curNode = getNode(root_element, "p", &parentNode);232 if (curNode == NULL) {233 printf("error: p node is not found");234 return -1;235 }236 if (parentNode == NULL) {237 // 根节点只能有一个子节点,这里就不处理了238 printf("error: This is root node, should treat specially. root node should have only one node");239 return -1;240 }241 removeNode(parentNode, curNode);242 243 244 // 重新获取跟节点,应该是main了245 root_element = xmlDocGetRootElement(doc);246 247 print_element_names(root_element, "after delete");248 249 /*free the document */250 xmlFreeDoc(doc);251 return 0;252 }253 254 int test_wrapWithNode(const char* filepath) {255 xmlDoc *doc = NULL;256 xmlNode *root_element = NULL;257 xmlNode *newNode = NULL;258 259 /*parse the file and get the DOM */260 doc = xmlReadFile(filepath, NULL, 0);261 262 if (doc == NULL) {263 printf("error: could not parse file %s\n", filepath);264 }265 266 /*Get the root element node */267 root_element = xmlDocGetRootElement(doc);268 269 // 增加一个父节点,根节点需要特殊处理270 xmlUnlinkNode(root_element);271 newNode = xmlNewNode(NULL, BAD_CAST "main");272 xmlAddChild(newNode, root_element);273 xmlDocSetRootElement(doc, newNode);274 // 重新获取跟节点,应该是main了275 root_element = xmlDocGetRootElement(doc);276 277 print_element_names(root_element, "after wrap");278 279 /*free the document */280 xmlFreeDoc(doc);281 282 return 0;283 }
https://segmentfault.com/q/1010000000581732
libxml
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。