diff --git a/xml-2/pom.xml b/xml-2/pom.xml index 025ad682ad..c4882b0a53 100644 --- a/xml-2/pom.xml +++ b/xml-2/pom.xml @@ -20,6 +20,12 @@ dom4j ${dom4j.version} + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter.version} + test + diff --git a/xml-2/src/main/java/com/baeldung/xml/validation/XmlErrorHandler.java b/xml-2/src/main/java/com/baeldung/xml/validation/XmlErrorHandler.java new file mode 100644 index 0000000000..2a4651a029 --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/validation/XmlErrorHandler.java @@ -0,0 +1,35 @@ +package com.baeldung.xml.validation; + +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXParseException; + +import java.util.ArrayList; +import java.util.List; + +public class XmlErrorHandler implements ErrorHandler { + + private List exceptions; + + public XmlErrorHandler() { + this.exceptions = new ArrayList<>(); + } + + public List getExceptions() { + return exceptions; + } + + @Override + public void warning(SAXParseException exception) { + exceptions.add(exception); + } + + @Override + public void error(SAXParseException exception) { + exceptions.add(exception); + } + + @Override + public void fatalError(SAXParseException exception) { + exceptions.add(exception); + } +} diff --git a/xml-2/src/main/java/com/baeldung/xml/validation/XmlValidator.java b/xml-2/src/main/java/com/baeldung/xml/validation/XmlValidator.java new file mode 100644 index 0000000000..7d8f531bfa --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/validation/XmlValidator.java @@ -0,0 +1,62 @@ +package com.baeldung.xml.validation; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import javax.xml.XMLConstants; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import java.io.File; +import java.io.IOException; +import java.util.List; + +public class XmlValidator { + + private static final Logger LOGGER = LoggerFactory.getLogger(XmlValidator.class); + + private String xsdPath; + private String xmlPath; + + public XmlValidator(String xsdPath, String xmlPath) { + this.xsdPath = xsdPath; + this.xmlPath = xmlPath; + } + + public boolean isValid() throws IOException, SAXException { + Validator validator = initValidator(xsdPath); + try { + validator.validate(new StreamSource(getFile(xmlPath))); + return true; + } catch (SAXException e) { + return false; + } + } + + public List listParsingExceptions() throws IOException, SAXException { + XmlErrorHandler xsdErrorHandler = new XmlErrorHandler(); + Validator validator = initValidator(xsdPath); + validator.setErrorHandler(xsdErrorHandler); + try { + validator.validate(new StreamSource(getFile(xmlPath))); + } catch (SAXParseException e) {} + xsdErrorHandler.getExceptions().forEach(e -> LOGGER.info(e.getMessage())); + return xsdErrorHandler.getExceptions(); + } + + private Validator initValidator(String xsdPath) throws SAXException { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Source schemaFile = new StreamSource(getFile(xsdPath)); + Schema schema = factory.newSchema(schemaFile); + return schema.newValidator(); + } + + private File getFile(String location) { + return new File(getClass().getClassLoader().getResource(location).getFile()); + } + +} diff --git a/xml-2/src/main/resources/xml/validation/baeldung.xml b/xml-2/src/main/resources/xml/validation/baeldung.xml new file mode 100644 index 0000000000..31ae4b4aa6 --- /dev/null +++ b/xml-2/src/main/resources/xml/validation/baeldung.xml @@ -0,0 +1,8 @@ + + + Baeldung +
+ 00001 + New York +
+
\ No newline at end of file diff --git a/xml-2/src/main/resources/xml/validation/full-person.xsd b/xml-2/src/main/resources/xml/validation/full-person.xsd new file mode 100644 index 0000000000..ea268c3a47 --- /dev/null +++ b/xml-2/src/main/resources/xml/validation/full-person.xsd @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xml-2/src/main/resources/xml/validation/person.xsd b/xml-2/src/main/resources/xml/validation/person.xsd new file mode 100644 index 0000000000..22c41b6a22 --- /dev/null +++ b/xml-2/src/main/resources/xml/validation/person.xsd @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xml-2/src/test/java/com/baeldung/xml/validation/XmlValidatorUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/validation/XmlValidatorUnitTest.java new file mode 100644 index 0000000000..2eb20a9bf2 --- /dev/null +++ b/xml-2/src/test/java/com/baeldung/xml/validation/XmlValidatorUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.xml.validation; + +import org.junit.jupiter.api.Test; +import org.xml.sax.SAXException; +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.*; + +class XmlValidatorUnitTest { + + private static final String BAELDUNG_XML_PATH = "xml/validation/baeldung.xml"; + private static final String PERSON_XSD_PATH = "xml/validation/person.xsd"; + private static final String FULL_PERSON_XSD_PATH = "xml/validation/full-person.xsd"; + + @Test + public void givenValidXML_WhenIsValid_ThenTrue() throws IOException, SAXException { + assertTrue(new XmlValidator(PERSON_XSD_PATH, BAELDUNG_XML_PATH).isValid()); + } + + @Test + public void givenInvalidXML_WhenIsValid_ThenFalse() throws IOException, SAXException { + assertFalse(new XmlValidator(FULL_PERSON_XSD_PATH, BAELDUNG_XML_PATH).isValid()); + } + + @Test + public void givenValidXML_WhenListParsingExceptions_ThenNone() throws IOException, SAXException { + assertEquals(0, new XmlValidator(PERSON_XSD_PATH, BAELDUNG_XML_PATH).listParsingExceptions().size()); + } + + @Test + public void givenInvalidXML_WhenListParsingExceptions_ThenHasThree() throws IOException, SAXException { + assertEquals(3, new XmlValidator(FULL_PERSON_XSD_PATH, BAELDUNG_XML_PATH).listParsingExceptions().size()); + } + +}