John Snelson wrote:
Hi Frank,
The cached grammars are owned by the XMLGrammarPool. If you don't
provide your own XMLGrammarPool to a parser, then it will use it's own,
which will be deleted when the parser is deleted.
You can share an XMLGrammarPool amongst threads by locking it using
XMLGrammarPool::lockPool(). Using this method, you should first populate
the grammar pool with the grammars you want. Then you can lock it and
construct as many parsers with it as you need.
The one problem I haven't solved using this method is that Xerces-C
refuses to parse an XML document with an internal DTD subset if the
grammar pool is locked. This means it is not compliant with the XML
specification :-(.
The easiest solution for this problem is to chain grammar pools
together. You can do it by implementing a GrammarPool that contains a
pointer to another, read-only GrammarPool that contains the Grammar
instances you want to cache. When the parser requests a Grammar, look
in the writable pool first. If it's not there, check the read-only
pool. When the parser wants to add a new Grammar to the pool, add it to
the writable pool. This also covers the case where the XML document has
an extra schema location hint.
You can also implement a schema like this using the GrammarResolver
interface, but using chained GrammarPool instances is simpler.
I devised a scheme like this when I worked at IBM on the XML database
implementation in DB2.
Dave