views:

810

answers:

2

Hi,

I'm validating against XMLSchema in Java, and getting SAXParseExceptions thrown when I have non-valid content models.

I'm going to be using these exceptions to highlight where the validation has failed - but the SAXParseExceptions seem to be a little too low-level.

For example, for a failure on an enumeration, I get the validity error that the value provided doesn't match the content model in one exception, and the element it applies to in the next.

I'm thinking I need to have a utility that abstracts a little to merge related errors together and parse exception text into useable exception properties.

Is this a reasonable approach, or am I just missing something, or maybe a library or helper class?


Update @timgilbert, thanks for the response.

For example, a SAXParseException I found on t'internet

cvc-pattern-valid: Value 'en' is not facet-valid
with respect to pattern '([a-zA-Z]{1,8})(-[a-zA-Z0-9]{1,8})*'

The key things for me are

  • Element 'en' to which this exception applies. Why can I not call exception.getElement() or something, and why not an XPath to the element in question? More useful with an in-memory document than the line and column number!
  • It's a pattern validation failure. Why can I not get something like a enumeration of possible types of failure and a reference to the appropriate one?
  • The actual pattern that validation has failed against.
  • There'll be another exception thrown next to tell me the value of the 'en' element that caused the problem that I need to merge

An example of what I'd like to be able to do is have people submit a document and have the document highlighted where validation fails with a user friendly message - the error message above kinda doesn't seem very friendly... having to parse by single quotes just feels like an accident waiting to happen :)

I think I'm maybe doing it wrong with the 'reference-to-element' thing, and perhaps I should have an identity transform of the document by default as part of the validation, and augment the transformation with validation-error attributes that I can pick out with CSS. That still won't help if I need to parse the messages to make them more friendly though...

Re: tight binding, javax.xml.validation.Validator.validate() throws org.xml.sax.SAXException anyway - not sure how I can get away from assuming the binding...

Cheers

+1  A: 

I'm not entirely clear about what you're asking here, maybe you could provide a little more detail about what you mean by the exceptions being too low-level? Is it that the error messages themselves are not comprehensible?

The SaxParseException class does have getColumnNumber() and getLineNumber() methods which you can present to the user to get them to fix the errors.

One thing that you might experiment with is using different XML-parsing implementations - every parser will throw an error when it finds invalid code, but different implementations may have different error messages and exception chains.

Actually, for this reason I'd be dubious about trying to build a library which inspects the exception chain and tries to build a more coherent error message out of it, since you'd be coupling your code fairly tightly to the specific details of an XML-parsing implementation (especially if you're relying on the specific verbiage of error messages).

(Sorry this isn't more specific, maybe you could give an example of the problem you're seeing?)

Tim Gilbert
A: 

Brabster I too faced the similar issue way back where I need to tell for which element in the xml the error has come. I solved the problem little bit by maintaining a stack in my handler of SAX Parser. In the startElement method I push the qName (name of the element) in the stack and in the endElement method I pop the qName from the stack.

Whenever an exception comes my stack represents the full XPath of the element.

The only problem was if there are multiple elements with the same name then you don't know the error is for which element. But at least the full XPath details helped along with the LineNumber and ColumnNumber.

Hope this helps.

Bhushan