Re: [xml] _private member of xmlParserCtxt in xmlExternalEntityLoader callback

Here is sample code which simulates our system - all data should be loaded
from database, so we need connection information inside external entity


xmlExternalEntityLoader defaultLoader;

// Load data from database

xmlParserInputPtr entLoader(const char *URL, const char* ID,
xmlParserCtxtPtr ctxt)


                xmlParserInputPtr out = 0;

std::cout << "URL = " << URL << "  _private ="

 << ctxt->_private << " state = " << ctxt->instate << std::endl;

                // Only can load files if _private contains connection info


                                out = defaultLoader(URL, ID, ctxt);    //
for testing - call standard loader


return out;


int main(int argc, char* argv[])



                // Initialize libxml



                xmlLoadExtDtdDefaultValue = 6;

                defaultLoader = xmlGetExternalEntityLoader();



                // Preloaded document can look like this..

                xmlChar *txt = (xmlChar*)"<?xml version=\"1.0\"

                                                "<!DOCTYPE book SYSTEM
\"dtd/book.dtd\" ["

                                                "<!ENTITY %
PublisherGraphics SYSTEM \"graphics.xml\">"


                                                "<!ENTITY frontmatter SYSTEM

                                                "<!ENTITY chapter1 SYSTEM


                xmlParserCtxtPtr ctxt = 0;

ctxt = xmlCreateDocParserCtxt(txt);


                // Database connection info

                                ConnectionInfo connection_info;


                                ctxt->_private = &connection_info;       //
Setup ctxt



                                // Work with parsed doc from ctxt->myDoc




                return 0;



Here is what I got from entLoader():

URL = graphics.xml  _private =0012FF58 state = 3
URL = dtd/ncbi-book.dtd  _private =0012FF58 state = 3
URL = dtd/e-xsl.dtd  _private =0012FF58 state = 3
URL = dtd/e-xsl/isoamsa.ent  _private =0012FF58 state = 3
URL = dtd/e-xsl/ncbibook.ent  _private =0012FF58 state = 3
URL = dtd/notations.dtd  _private =0012FF58 state = 3
URL = dtd/e-xsl/ncbibook.ent  _private =0012FF58 state = 3
URL = fm.xml  _private =00000000 state = 0
URL = chapters/ch1_.xml  _private =00000000 state = 0

I've debugged the code with Visual C++ debugger and found inside parser.c :

static int
xmlParseExternalEntityPrivate(... , xmlParserCtxtPtr oldctxt, ...)
ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);  // <-- inside this
function new ParserCtxt  will be created and _private member will not be
copied from oldctxt

Call stack:
xmlParseExternalEntityPrivate() < xmlParseReference() < xmlParseContent() <
xmlParseElement() < xmlParseDocument() < main()....

inside xmlCreateEntityParserCtxt () I found call to external entity loader
with newly created xmlParserCtxt
I've created new function

xmlCreateEntityParserCtxtWithData(const xmlChar *URL, const xmlChar *ID,
const xmlChar *base, void *data);

the only difference from xmlCreateEntityParserCtxt is las parameter which I
assign to _private memeber of new xmlParserCtxt
This solves my problem. May be it will be usefull for our people - if so, I
can send my libxml2 changes
I've also checked all other calls to xmlCreateEntityParserCtxt for entire
library and found only 3 of them. I think it will be safe to change them
to xmlCreateEntityParserCtxtWithData.


----- Original Message -----
From: "Daniel Veillard" <veillard redhat com>
To: "Asorokin" <asorokin ncbi nlm nih gov>
Cc: <xml gnome org>
Sent: Wednesday, September 25, 2002 6:55 PM
Subject: Re: [xml] _private member of xmlParserCtxt in
xmlExternalEntityLoader callback

On Wed, Sep 25, 2002 at 03:21:08PM -0400, Asorokin wrote:
I'm trying to use my private data inside  redefined external entity
Inside my callback I found what if parser state ctxt->instate is equal
then ctxt->_private is NULL . In other parser states the _private member
seems to be Ok.

  When do you set-up ctxt->_private ?

For some reasons I can't use global variable to get my private data
callback. Can anybody
suggest how to get private data inside redefined external entity loader
when ctxt->instate == XML_PARSER_START

  A priori I don't see why you would have this behaviour, but it all
depend when you initialize it and the kind of interface you use, are
you using the push parser interface. Give more informations, this
is not sufficient !


Daniel Veillard      | Red Hat Network
veillard redhat com  | libxml GNOME XML XSLT toolkit | Rpmfind RPM search engine

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