NikWhitfield
asked on
XML / Schema validation - need error node
Hi -
I'm running validation for an XML file against an xsd schema using MSXML4. I do this using the following code:
Dim objReader As New MSXML2.SAXXMLReader40 '- Create a SAX reader.
Dim objValidator As clsXMLEventHandler '- Create an instance of the class module that implements the IVBSAXErrorHandler interface
Const VALIDATE_FEATURE As String = "schema-validation"
Const EXHAUSTIVE_FEATURE As String = "exhaustive-errors"
Const VALIDATE_TYPE_PROPERTY As String = "schemas"
'Assume failure
ValidateXML = False
'Instantiate the event handler
Set objValidator = New clsXMLEventHandler
'Setup the validator
objValidator.XML = pobjDOMDoc.XML
'Configure the SAX reader to validate the XML document.
With objReader
.putFeature VALIDATE_FEATURE, True
.putFeature EXHAUSTIVE_FEATURE, True
.putProperty VALIDATE_TYPE_PROPERTY, mobjSchemaCache
'Assign an instance of the MyValidator class to the errorHandler property of the SAX reader.
Set .ErrorHandler = objValidator
'Parse and validate the xml.
.parse pobjDOMDoc.XML
End With
This uses an event handler class which implements IVBSAXErrorHandler. This catches validation errors in subroutines like this one:
IVBSAXErrorHandler_error(B yVal oLocator As MSXML2.IVBSAXLocator, strErrorMessage As String, ByVal nErrorCode As Long)
This is great and gives me some useful info. However, what I could really do with is the Node object for which the error was thrown.
Does anyone know how I would go about getting hold of the node object? I've got the line number and column, and a copy of the .XML text - how would I go about finding the required node??
Answers on a postcard....
Thanks, Nik
I'm running validation for an XML file against an xsd schema using MSXML4. I do this using the following code:
Dim objReader As New MSXML2.SAXXMLReader40 '- Create a SAX reader.
Dim objValidator As clsXMLEventHandler '- Create an instance of the class module that implements the IVBSAXErrorHandler interface
Const VALIDATE_FEATURE As String = "schema-validation"
Const EXHAUSTIVE_FEATURE As String = "exhaustive-errors"
Const VALIDATE_TYPE_PROPERTY As String = "schemas"
'Assume failure
ValidateXML = False
'Instantiate the event handler
Set objValidator = New clsXMLEventHandler
'Setup the validator
objValidator.XML = pobjDOMDoc.XML
'Configure the SAX reader to validate the XML document.
With objReader
.putFeature VALIDATE_FEATURE, True
.putFeature EXHAUSTIVE_FEATURE, True
.putProperty VALIDATE_TYPE_PROPERTY, mobjSchemaCache
'Assign an instance of the MyValidator class to the errorHandler property of the SAX reader.
Set .ErrorHandler = objValidator
'Parse and validate the xml.
.parse pobjDOMDoc.XML
End With
This uses an event handler class which implements IVBSAXErrorHandler. This catches validation errors in subroutines like this one:
IVBSAXErrorHandler_error(B
This is great and gives me some useful info. However, what I could really do with is the Node object for which the error was thrown.
Does anyone know how I would go about getting hold of the node object? I've got the line number and column, and a copy of the .XML text - how would I go about finding the required node??
Answers on a postcard....
Thanks, Nik
Postcard from Rat's Hole:
Having a nice time, wish you were here!
Rat.
Tell me different if I'm stupid, but SAX does not create nodes like DOM. So how can the event signify the node?
Having a nice time, wish you were here!
Rat.
Tell me different if I'm stupid, but SAX does not create nodes like DOM. So how can the event signify the node?
NikWhitfield,
Of course BigRat is correct.
If you look at the MSXML API, a "node" is actually an IXMLDOMNode object, which gives you a clue as to which mechanism is used to create them. SAX implementations are event-driven, and doesn't create any internal representation of the document (it just tells you when certain conditions are encountered while processing the document in a serial fasion), whereas DOM implementations will parse and internalise the entire document before making it available to applications through the various hierarchically-organised DOM node types.
Regards,
WMB
Of course BigRat is correct.
If you look at the MSXML API, a "node" is actually an IXMLDOMNode object, which gives you a clue as to which mechanism is used to create them. SAX implementations are event-driven, and doesn't create any internal representation of the document (it just tells you when certain conditions are encountered while processing the document in a serial fasion), whereas DOM implementations will parse and internalise the entire document before making it available to applications through the various hierarchically-organised DOM node types.
Regards,
WMB
ASKER
Both correct.
My thoughts were that there may be some mechanism between SAX and DOM, such that it is possible to identify a node based on the line number and column number returned in the IVBSAXLocator.
Having looked around a while, nothing like this does exist! I've written something with some degree of success, but not a complete solution by any means.
My thoughts were that there may be some mechanism between SAX and DOM, such that it is possible to identify a node based on the line number and column number returned in the IVBSAXLocator.
Having looked around a while, nothing like this does exist! I've written something with some degree of success, but not a complete solution by any means.
Is the document so big that it couldn't be loaded into a DOM?
ASKER
Nope -
but with the SAX parser, I can get multiple errors on validation, i.e. parse all errors / warnings in one go, as oppose to find an error, raise it, correct problem, find next error, etc.
but with the SAX parser, I can get multiple errors on validation, i.e. parse all errors / warnings in one go, as oppose to find an error, raise it, correct problem, find next error, etc.
Yes, I see. Then you can fix them all at once rather than one at a time (ever tried programming with Borland Turbo Pascal?).
Still other than "last-tag-seen" there's not much else!
Still other than "last-tag-seen" there's not much else!
ASKER
I think the aforementioned 'last-tag-seen' is the only way to go... unfortunately, it seems that MSXML sometimes returns errors against the wrong attribute, for example ...
Multiple error validation is damned important - for all you know, there are 6000 errors in your schema! You could get pretty pissed off with not knowing the total before you set out to correct them all...
Multiple error validation is damned important - for all you know, there are 6000 errors in your schema! You could get pretty pissed off with not knowing the total before you set out to correct them all...
A request has been made by the Asker that this question be deleted.
EXPERTS: Please leave your thoughts here; I will return in seven (7) days to resolve the question.
Netminder
CS Moderator
EXPERTS: Please leave your thoughts here; I will return in seven (7) days to resolve the question.
Netminder
CS Moderator
OK, but it's a pity about the cheese!
ASKER
Bigrat,
sorry, but I managed to implement this functionality myself (with some ultra unpleasant code!). If you'd like to see it, then let me know and I'll forward you the stuff.
Nik
sorry, but I managed to implement this functionality myself (with some ultra unpleasant code!). If you'd like to see it, then let me know and I'll forward you the stuff.
Nik
Doesn't IVBSAXErrorHandler give you what you need?
What I mean to say is, this looks like the same error handler provided by Xerces, etc, and it returns line number, position and node name in its error report.
What other information are you looking for? Maybe there's a cleaner workaround? What is your current workaround?
What other information are you looking for? Maybe there's a cleaner workaround? What is your current workaround?
ASKER
Not that I can find
Xerces, of course, also has a DOM error handler which would give you what you need if you were able to use it, but I'm guessing that's not an option?
Xerces, of course, also has a DOM error handler which would give you what you need if you were able to use it, but I'm guessing that's not an option?
Xerces, of course, also has a DOM error handler which would give you what you need if you were able to use it, but I'm guessing that's not an option?
Actually, Nik, I realised what I just wrote isn't strictly true -- Xerces (actually the w3 DOM API) uses the SAX error handler to report DOM errors, so you get the exact same error info, but you would get all of them.
I guess the key problem is that DOM won't expose any Node objects until the document is completely parsed and built.
I guess the key problem is that DOM won't expose any Node objects until the document is completely parsed and built.
ASKER
The basic problem is that SAX will not return an actual DOM node object. I've done a load of gymnastics to find an appropriate node using the error position in the XML file. It's really convoluted, but returns a node in the end, if indeed it was a node which errored (I'm not currently concerned with attributes).
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER