Subject: | Suggestion for XML::SAX::Intro pod |
I have come across an issue with XML::Validator::Schema's implementation that prohibits me from using this class as-is as the first filter in an XML::SAX::Pipeline. XML::Validator::Schema's implementation relies on returning an XML::Filter::BufferText instance whose "Handler" instance variable is set to an XML::Validator::Schema instance that does the real work of validating the incoming XML (XML::Filter::BufferText is required so that the XML::Validator::Schema instance sees a single "characters" SAX event to validate the value provided within a given element's definition).
The problem is that this presumes that the XML::Filter::BufferText instance's handler will always be assigned to the XML::Validator::Schema instance. When I to use this class with XML::SAX::Pipeline, as in:
$validator = XML::Validator::Schema->new($someXSDfile);
$secondFilter = My::XML::Filter::SomeFilter->new();
$thirdFilter = My::XML::Filter::SomeOtherFilter->new();
$pipeline = XML::SAX::Pipeline->new($validator, $secondaryFilter,
$thirdFilter);
$validator->{Handle} gets reset to point to $secondaryFilter as the
pipeline machine is built. This destroys the presumption made by XML::Validator::Schema that the object XML::Validator::Schema->new() returned had a specific handler defined that referred to an object that would do the real work.
Yes, this is an issue for the owner of XML::Validator::Schema, Sam Tregar, to resolve (and I have communicated this problem to Sam), but it would be useful if an explicit statement were included in XML::SAX::Intro warning writers of Filter classes not to rely on any pre-defined handlers. If one defines a Filter class, the filter should:
a) Implement a set_handler() method that XML::SAX::Pipeline can use to
assign handlers as it builds the pipeline machine.
b) NOT presume any pre-existing handler will be assigned or maintained
if the filter is used to build a pipeline (or any other type of SAX)
machine.
This might help future Filter writers avoid the problem that exists now with XML::Validator::Schema.
Yes the above is obvious in how XML::SAX::Pipeline and XML::SAX::Machines build pipeline and other machines, but it would not hurt to be even more explicit about this. It might also be useful to provide an example of the "good" way of doing this and the "wrong" way.
For now, I have implemented a subclass of XML::Validator::Schema (shown as MY_XML::Validator::Schema in the example below) that returns the real XML::Validator::Schema instance that the XLM::Filter::BufferText instance's Handler instance variable refers to, and then constructed my SAX pipeline using:
$bufferTextFilter = XML::Filter::BufferText->new();
$validator = MY_XML::Validator::Schema->new($someXSDfile);
$secondFilter = My::XML::Filter::SomeFilter->new();
$thirdFilter = My::XML::Filter::SomeOtherFilter->new();
$pipeline = XML::SAX::Pipeline->new($bufferTextFilter,
$validator, $secondaryFilter,
$thirdFilter);
This solves my problem temporarily, but requires too much knowledge about XML::Validator::Schema's implementation.