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

Reply via email to