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

时间: 2024-08-07 16:05:25

libxml的相关文章

fatal error: &#39;libxml/xmlversion.h&#39; file not found

问题: MACOS安装scrapy时,安装lxml出现错误 In file included from src/lxml/lxml.etree.c:232: /tmp/easy_install-O2UfP7/lxml-3.4.0/src/lxml/includes/etree_defs.h:14:10: fatal error: 'libxml/xmlversion.h' file not found #include "libxml/xmlversion.h"          ^

iOS_导入libxml2.2框架后,找不到&lt;libxml/tree.h&gt;的解决办法

由于用到了第三方Html解析类库Hpple, 在导入框架libxml2.2.dylib后, 最到了XCode仍然找不到<libxml/tree.h>的情况, 最后解决过程如下: 1.项目-Targets中的Build Phases, 找到Link Binary With Libraries, 点击"+",添加 "libxml2.dylib" 2.同样的,切换到Buiild Settings的tab里, 通过搜索,找到"Linking"

libxml/HTMLparser.h file not found

在导入asihttprequest包时出问题导入了libxml2.dylib.可是却提示libxml/HTMLparser.h file not found. 这是由于你的开发环境默认的路径无法找到这个libxml2.dylib框架. 改动方法:(1)第一种方法:(我的可行)点击左边项目的根文件夹,再点击右边的Build Settings,手工输入文字:"Header search paths".然后单击(或双击.点击弹出面板以下的"+"号进行加入)"He

XML解析适配 &#39;libxml/tree.h&#39;file not found 错误解决办法

Xcode 'libxml/tree.h'file not found 错误解决办法 在工程的"Build Settings"页中找到"Header Search Path"项,添加"/usr/include/libxml2".在"Other Linker Flags"项,添加"-lxml2" XML解析适配 'libxml/tree.h'file not found 错误解决办法

UI进阶 XML解析适配 &#39;libxml/tree.h&#39;file not found 错误解决办法

Xcode 'libxml/tree.h'file not found 错误解决办法 在工程的"Build Settings"页中找到"Header Search Path"项,添加"/usr/include/libxml2".在"Other Linker Flags"项,添加"-lxml2" UI进阶 XML解析适配 'libxml/tree.h'file not found 错误解决办法

libXml ARC forbids explicit message send of&#39;release&#39;

'release' is unavailable: not available in automatic reference counting mode ARC forbids explicit message send of'release' 'release' is unavailable: not available inautomatic reference counting mode 解决办法: 打开当前工程,打开"Build Settings",找到Objective-C

libxml的使用(4)--xpath搜索节点树

在libxml的tutorial中介绍了一种用关键字查找节点的方法,这种方法将使用打xpath系列API.由于我才刚刚接触libxml,所以我对xpath的认识也仅仅是在tutorial提供的功能之内了.废话少说,直接进入整体. 我们在操作xml文件是经常需要根据特定的条件查找一系列的节点,为了实现这样的功能,我们需要一个xmlXPathContextPtr和一个expression.我们调用xmlXPathEvalExpression函数来得到一个xmlXPathObjectPtr指针,这个指

libxml的使用(1)--读取xml

libxml是一个用于解析xml文件的库,在各个平台下都能使用,也支持多种语言,如c,Python等.这里是官方网站.上面有libxml的api和一些code examples,都是英文的.不过比较简单. libxml的基础功能就是对xml的读和写.下面将简单介绍libxml的读的功能.(大部分内容是参照libxml tutorial 的文档) 0 编译程序 因为本人是在Linux下用C语言来介绍libxml的,所以使用了gcc编译器.其他的编译命令请参照官网. 我们知道,gcc 最简单的编译命

python 2.7安装某些包出现错误:&quot;libxml/xmlversion.h:没有那个文件或目录&quot;

解决办法: 1. ubuntu系统: 首先: 1 apt-get install libxml2-dev 2 sudo ln -s /usr/include/libxml2/libxml /usr/include/libxml 然后: 1 apt-get install libxslt-dev