Merge pull request #12478 from thibaultfaure/articles/BAEL-5671-validate-an-xml-file-against-an-xsd
BAEL-5671 code for the validate an XML file against an XSD file article
This commit is contained in:
		
						commit
						b6e04505ef
					
				| @ -20,6 +20,12 @@ | ||||
|             <artifactId>dom4j</artifactId> | ||||
|             <version>${dom4j.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.junit.jupiter</groupId> | ||||
|             <artifactId>junit-jupiter-api</artifactId> | ||||
|             <version>${junit-jupiter.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <build> | ||||
|  | ||||
| @ -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<SAXParseException> exceptions; | ||||
| 
 | ||||
|     public XmlErrorHandler() { | ||||
|         this.exceptions = new ArrayList<>(); | ||||
|     } | ||||
| 
 | ||||
|     public List<SAXParseException> 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); | ||||
|     } | ||||
| } | ||||
| @ -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<SAXParseException> 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()); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										8
									
								
								xml-2/src/main/resources/xml/validation/baeldung.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								xml-2/src/main/resources/xml/validation/baeldung.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" ?> | ||||
| <individual> | ||||
|     <name>Baeldung</name> | ||||
|     <address> | ||||
|         <zip>00001</zip> | ||||
|         <city>New York</city> | ||||
|     </address> | ||||
| </individual> | ||||
							
								
								
									
										25
									
								
								xml-2/src/main/resources/xml/validation/full-person.xsd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								xml-2/src/main/resources/xml/validation/full-person.xsd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" ?> | ||||
| <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> | ||||
|     <xs:element name="individual"> | ||||
|         <xs:complexType> | ||||
|             <xs:sequence> | ||||
|                 <xs:element name="name"> | ||||
|                     <xs:simpleType> | ||||
|                         <xs:restriction base="xs:string"> | ||||
|                             <xs:maxLength value="5" /> | ||||
|                         </xs:restriction> | ||||
|                     </xs:simpleType> | ||||
|                 </xs:element> | ||||
|                 <xs:element name="address"> | ||||
|                     <xs:complexType> | ||||
|                         <xs:sequence> | ||||
|                             <xs:element name="zip" type="xs:positiveInteger" /> | ||||
|                             <xs:element name="city" type="xs:string" /> | ||||
|                             <xs:element name="street" type="xs:string" /> | ||||
|                         </xs:sequence> | ||||
|                     </xs:complexType> | ||||
|                 </xs:element> | ||||
|             </xs:sequence> | ||||
|         </xs:complexType> | ||||
|     </xs:element> | ||||
| </xs:schema> | ||||
							
								
								
									
										18
									
								
								xml-2/src/main/resources/xml/validation/person.xsd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								xml-2/src/main/resources/xml/validation/person.xsd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" ?> | ||||
| <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> | ||||
|     <xs:element name="individual"> | ||||
|         <xs:complexType> | ||||
|             <xs:sequence> | ||||
|                 <xs:element name="name" type="xs:string" /> | ||||
|                 <xs:element name="address"> | ||||
|                     <xs:complexType> | ||||
|                         <xs:sequence> | ||||
|                             <xs:element name="zip" type="xs:positiveInteger" /> | ||||
|                             <xs:element name="city" type="xs:string" /> | ||||
|                         </xs:sequence> | ||||
|                     </xs:complexType> | ||||
|                 </xs:element> | ||||
|             </xs:sequence> | ||||
|         </xs:complexType> | ||||
|     </xs:element> | ||||
| </xs:schema> | ||||
| @ -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()); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user