I know I can validate xml-file when I use sax. But can I validate when I use Stax?
stax xml validation
Asked Answered
There are two ways of XML validation possible with SAX and DOM:
- validate alone - via Validator.validate()
- validate during parsing - via DocumentBuilderFactory.setSchema() and SAXParserFactory.setSchema()
With StAX, validation is possible, but only the first way of doing it.
You can try something like this:
import javax.xml.validation.*;
import javax.xml.transform.stax.*;
import javax.xml.stream.*;
import javax.xml.*;
import java.io.*;
public class StaxValidation {
public static void main (String args[]) throws Exception {
XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new FileInputStream("test.xml"));
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new File("test.xsd"));
Validator validator = schema.newValidator();
validator.validate(new StAXSource(reader));
//no exception thrown, so valid
System.out.println("Document is valid");
}
}
You can parse and validate with StAX in one pass. Use javax.xml.stream.util.StreamReaderDelegate:
XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new FileInputStream ("test.xml"));
reader = new StreamReaderDelegate(reader) {
public int next() throws XMLStreamException {
int n = super.next();
// process event
return n;
}};
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new File("test.xsd"));
Validator validator = schema.newValidator();
validator.validate(new StAXSource(reader));
Validator reads test.xml calling reader.next() and you process parsing events as usual.
I'd note that you cannot use things like XMLStreamReaderImpl.getElementText(), for convenience in your delegated next() method, as it moves the current position ahead, which will confuse the validator. But that can be worked around - I like it. –
Kaylakayle
Does it make sense to have a 1 pass stream parser and validator? As long as the validation has not finished, you can not do anything with the data but buffering it in memory. When the validation finishes, you have read all data into memory and your stream reader has mutated into a DOM reader. –
Suffumigate
@Suffumigate I can imagine reading the data and saving it into a transactional database. In the end, if the document turned out to be valid, then commit the transaction, otherwise perform a rollback. –
Dearing
There is no standard way to do this. However, there's an API extension called StAX2 which support validation using Sun's MSV (multi schema validation). I would recommend to use the Woodstox StAX2 implementation.
© 2022 - 2024 — McMap. All rights reserved.