• 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:
    ");
     82     test_removeNode(argv[1]);
     83 
     84     printf("
    
    test: wrapWithNode
    ");
     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
    ", 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
    ", 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>
    ", LEVELS[level], cur_node->name, cur_node->type);
    122             printTree(cur_node->children, level + 1);
    123         } else {
    124             printf("%s#%s <%d>
    ", 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
    ", siblingNode->name);
    164             break;
    165         }
    166 
    167         siblingNode = siblingNode->next;
    168     }
    169 
    170     printf("debug: parentNode: %s, nodeToDelete: %s
    ", parentNode->name, nodeToDelete->name);
    171     printTree(parentNode, 0);
    172 
    173     xmlNode *childrenNode = nodeToDelete->children;
    174     if (childrenNode == NULL) {
    175         printf("warn: childrenNode is null
    ");
    176     }
    177     //xmlUnlinkNode(nodeToDelete->children);
    178 
    179     xmlNodePtr nextChildNode = NULL;
    180 
    181     while (childrenNode != NULL) {
    182         printf("debug: childrenNode: %s
    ", childrenNode->name);
    183         nextChildNode = childrenNode->next;
    184         xmlUnlinkNode(childrenNode);
    185 
    186         if (siblingNode != NULL) {
    187             printf("debug: addPreSibling: %s, sibling is %s
    ", childrenNode->name, siblingNode->name);
    188             xmlAddPrevSibling(siblingNode, nextChildNode);
    189         } else {
    190             printf("debug: addChild: %s, parent is %s
    ", 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
    ", 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
    ", 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

  • 相关阅读:
    python命令方式和关键字
    python注释及语句分类
    基于物联网的智能垃圾桶设计
    基于51单片机的交通灯控制设计
    python安装以及版本检测
    python简介
    关于deepin系统安装design compiler的问题解答
    关于安装deepin+window10双系统有时没有声音的问题
    如何使用notepad运行python程序
    15 一个完整的链式队列代码
  • 原文地址:https://www.cnblogs.com/catgatp/p/6613702.html
Copyright © 2020-2023  润新知