Re: [xml] Questions on usage: xmlTextReaderCurrentDoc, XPath and xmlTextReaderRead



 "William M. Brack" wrote:

I'm responding to your questions on Valgrind, but leaving the
questions on Text Reader vs. XPath to others:

Much thanks for a quick response!


Eric West wrote:
[disclaimer: I am new to coding with libxml2]

Good reason to rely heavily on libxml2/doc/examples for code models.

I have a test program to write and read some sample xml. It "works",
but I have noticed that valgrind reports some problems related 
to xmlTextReaderRead and xmlNewTextReaderFilename.

Using Valgrind on your programs is a GOOD thing.  I only wish more
would follow your example.

[Details below]

My test program uses the TextReader APIs to extract XML content. At
parent nodes, it utilizes XPath queries to extract child and grandchild 
content. In pseudocode, this is

     reader = xmlNewReaderFilename();
     ret = xmlReaderRead( reader);
     doc = xmlTextReaderCurrentDoc( reader);
     while ( ret == 1) {
           processNode( reader, doc);
           xmlTextReaderRead( reader);
      }

      xmlFree( doc);

There is room for improvement here - check what reader3.c and
reader4.c do with the doc returned by xmlTextReaderCurrentDoc. 
(Hint: they *don't* use xmlFree for this).


Improvement indeed! Further investigation showed that xmlFree() is 
not always the correct API for releasing memory allocated by libxml2
<sigh>The API docs are not always clear about this. Example:
for xmlXPathEval() "the xmlXPathObjectPtr resulting from the
evaluation or NULL. the caller has to free the object." Not a word
about xmlXPathFreeObject(). Replacing xmlFree() with the appropriate
object free routines started making valgrind happier.

What was not obvious in the xmlTextReader+XPath example was where
to get a pointer to the current xmlDocPtr without calling
xmlTextReaderCurrentDoc(). I did some further experimenting and
found that one may use the xmlDocPtr from the xmlNodePtr returned
by xmlTextReaderExpand(). For example:

   node = xmlTextReaderExpand( reader);
   pathContext = xmlXPathNewContext( node->doc);
   pathContext->node = node;
   obj = xmlXPathEval( BAD_CAST xmlXPathQuery, pathContext);

With this revision of my code and replacement of xmlFree() with
the appropriate variant (eg xmlXPathFreeObject, xmlXPathFreeContext)
I was able to get valgrind to give my code a clean bill of health.

Question: is the above code sequence valid??? (Just because it works,
is not much of a measure of correctness. :)  )

Thanks.

  --Eric
-- 
E r i c   W e s t
B o s t o n ,   M A



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]