This post shows how to validate XML string data against XSD files in Java. Most of the time, we work directly with XML files instead of string format. We point to an XML file and validate it against XSDs. However, we can validate XML content as a string against XSDs files without converting it to a file.
Validate XML Files Against XSDs
To make a point, consider the following codes. The codes refer to a file instead of a string, and the xmlFilePath variable points to a file.
1 2 3 4 5 6 7 8 9 10 11 12 | public static boolean validateXMLFileAgainstSchema(String xsdFilePath, String xmlFilePath){ try { SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = factory.newSchema(new File(xsdFilePath)); Validator validator = schema.newValidator(); validator.validate(new StreamSource(new File(xmlFilePath))); } catch (IOException | SAXException e) { System.out.println(e.getMessage()); return false; } return true; } |
Marshall to JAXB Object To String Or Craft An XML String
First, we need codes to convert a JAXB object to a String object. We can do this by marshaling an object to a StringWriter. Alternatively, we could craft XML data as a string. For this post, convert a JAXB object to a string object. Consider the following method.
1 2 3 4 5 6 7 8 9 10 11 12 13 | public static <T> String marshalObjectToString(T object, Class<T> clazz) throws Exception { JAXBContext jaxbContext = JAXBContext.newInstance(clazz); Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); // output pretty printed jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, false); StringWriter sw = new StringWriter(); jaxbMarshaller.marshal(object, sw); return sw.toString(); } |
From the StringWriter object, we can generate a String object.
Validate XML String
We can use the String object to compare against an XSD. Consider the following codes. Notice we use a string that represents an XML. See lines 10 – 13. However, the XSDs are still in a file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public static void validate(String xmlString) throws Exception { String xsdFile = "//somewhere/myxsd.xsd"; SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = schemaFactory.newSchema(new Source[] { new StreamSource( new File(xsdFile)) }); StringReader stringReader = new StringReader(xmlString); schema.newValidator().validate( new StreamSource(stringReader) ); stringReader.close(); } |
Validate XML String Usage
Finally, we can put the methods together and test things out. Consider the following codes. Given a JAXB class, we can an object of that class. Then, we pass that object to the marshalObjectToString method. Next, we get a string, and we give it to the validate method where the validation takes place.
1 2 3 4 5 6 7 8 | // JAXB class Student student = new Student(); // Convert object to a String representation String jaxbToXml = marshalObjectToString(student, Student.class); // Validate XML against an XSD validate(jaxbToXml); |
If the string has errors or does not conform to the XSDs, the codes return an Exception. Otherwise, the application runs past that call to the validate method.
And that’s how we can validate XML string instead of using XML files. Which technique to use then? It depends on your requirements. Generally, if the XML data is relatively small, we can use XML string instead. Otherwise, use XML files, especially for background processing.