[xml] xmlNodeSetContent trouble
- From: wayne taxupdate com
- To: xml gnome org
- Subject: [xml] xmlNodeSetContent trouble
- Date: Sat, 23 Jul 2005 15:47:08 -0500
I'm trying to learn by modifying the example code from the web site. The
following works (with parser warnings & error messages):
1. #include <stdio.h>
2. #include <libxml/parser.h>
3. #include <libxml/tree.h>
4. #include <libxml/xpath.h>
5. #include <assert.h>
6.
7.
8. /**
9. * update_xpath_nodes:
10. * @nodes: the nodes set.
11. * @value: the new value for the node(s)
12. *
13. * Prints the @nodes content to @output.
14. */
15.static void
16.update_xpath_nodes(xmlNodeSetPtr nodes, const xmlChar* value) {
17. int size;
18. int i;
19.
20. assert(value);
21. size = (nodes) ? nodes->nodeNr : 0;
22.
23. /*
24. * NOTE: the nodes are processed in reverse order, i.e. reverse document
25. * order because xmlNodeSetContent can actually free up descendant
26. * of the node and such nodes may have been selected too ! Handling
27. * in reverse order ensure that descendant are accessed first, before
28. * they get removed. Mixing XPath and modifications on a tree must be
29. * done carefully !
30. */
31. for(i = size - 1; i >= 0; i--) {
32. assert(nodes->nodeTab[i]);
33.
34. xmlNodeSetContent(nodes->nodeTab[i], value);
35. /*
36. * All the elements returned by an XPath query are pointers to
37. * elements from the tree *except* namespace nodes where the XPath
38. * semantic is different from the implementation in libxml2 tree.
39. * As a result when a returned node set is freed when
40. * xmlXPathFreeObject() is called, that routine must check the
41. * element type. But node from the returned set may have been removed
42. * by xmlNodeSetContent() resulting in access to freed data.
43. * This can be exercised by running
44. * valgrind xpath2 test3.xml '//discarded' discarded
45. * There is 2 ways around it:
46. * - make a copy of the pointers to the nodes from the result set
47. * then call xmlXPathFreeObject() and then modify the nodes
48. * or
49. * - remove the reference to the modified nodes from the node set
50. * as they are processed, if they are not namespace nodes.
51. */
52. if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL)
53. nodes->nodeTab[i] = NULL;
54. }
55.}
56.
57./**
58. * example1Func:
59. * @filename: a filename or an URL
60. *
61. * Parse the resource and free the resulting tree
62. */
63.static int
64.replaceValue(xmlDocPtr doc, const xmlChar * xpathExpr, const xmlChar * value) {
65. xmlXPathContextPtr xpathCtx;
66. xmlXPathObjectPtr xpathObj;
67.
68. /* Create xpath evaluation context */
69. xpathCtx = xmlXPathNewContext(doc);
70. if(xpathCtx == NULL) {
71. fprintf(stderr,"Error: unable to create new XPath context\n");
72. xmlFreeDoc(doc);
73. return(-1);
74. }
75.
76. /* Evaluate xpath expression */
77. xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
78. if(xpathObj == NULL) {
79. fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr);
80. xmlXPathFreeContext(xpathCtx);
81. xmlFreeDoc(doc);
82. return(-1);
83. }
84.
85. /* update selected nodes */
86. update_xpath_nodes(xpathObj->nodesetval, value);
87.
88. /* Cleanup of XPath data */
89. xmlXPathFreeObject(xpathObj);
90. xmlXPathFreeContext(xpathCtx);
91.
92. /* dump the resulting document */
93. xmlDocDump(stdout, doc);
94.
95.
96. xmlFreeDoc(doc);
97. return 0;
98.}
99.
100int main(int argc, char **argv) {
101 xmlDocPtr doc;
102 int retval;
103 if (argc != 2){
104 fprintf(stderr, "Usage: %s path\n", argv[0]);
105 return(1);
106 }
107
108 /*
109 * this initialize the library and check potential ABI mismatches
110 * between the version it was compiled for and the actual shared
111 * library used.
112 */
113 LIBXML_TEST_VERSION
114
115 //doc = xmlReadFile(argv[1], NULL, XML_PARSE_NOERROR + XML_PARSE_NOWARNING);
116 doc = xmlParseFile(argv[1]);
117 if (doc == NULL) {
118 fprintf(stderr, "Error: unable to parse file \"%s\"\n", argv[1]);
119 return(-1);
120 }
121
122 retval = replaceValue(doc, BAD_CAST "/gnc-v2/book/count-data[ type='account']/text()", BAD_CAST "*");
123
124 /*
125 * Cleanup function for the XML library.
126 */
127 xmlCleanupParser();
128 /*
129 * this is to debug memory for regression tests
130 */
131 xmlMemoryDump();
132 return(retval);
133}
However, if I use line 115 instead of 116, I get no parser messages, but get this:
*** glibc detected *** free(): invalid pointer: 0x08052c53 ***
which occurs at line 34. Any suggestions?
Wayne
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]