Xsd validation in java

Validate XML against XSD Schema using Java

In this example we will Validate XML against XSD Schema. We use the javax.xml.validation.Validator to check the XML document against the XSD schema. Be careful because the validator is not thread safe. It is the responsibility of the application to make the code thread safe. The validation is successful when the validator.validate() method does not throw an exception.

Project structure

+--src | +--main | +--java | +--com | +--memorynotfound | |--ValidateXmlXsd.java | +--resources | |--schema.xsd pom.xml

XSD Schema

XSD Validator

To validate XML against XSD schema we need to create a schema and a validator. Next we validate the XML against the XSD schema. The validation is successful if the validator.validate() method does not throw an exception.

Warning: A validator is NOT thread save. It is the responsibility of the application to make sure that one Validator object is not used from more than one thread at any given time.

package com.memorynotfound.xml.xsd; import org.xml.sax.SAXException; import javax.xml.XMLConstants; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import java.io.IOException; import java.io.StringReader; public class ValidateXmlXsd < public static String xml = "\n" + "JAX-B\n" + " Validate XML against XSD Schema\n" + ""; public static void main(String. args) < try < System.out.println("Validate XML against XSD Schema"); SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = factory.newSchema(ValidateXmlXsd.class.getResource("/schema.xsd")); Validator validator = schema.newValidator(); validator.validate(new StreamSource(new StringReader(xml))); System.out.println("Validation is successful"); >catch (IOException e) < // handle exception while reading source >catch (SAXException e) < System.out.println("Error when validate XML against XSD Schema"); System.out.println("Message: " + e.getMessage()); >> >

Getting the line and column number

If you need to display the line or column number, read this tutorial.

Читайте также:  Css not last child selector

Output

Validate XML against XSD Schema Error when validate XML against XSD Schema Message: cvc-datatype-valid.1.2.1: '1-ID' is not a valid value for 'integer'.

References

Источник

Валидация XML с помощью XSD, JAXB и Spring Framework

Здравствуйте! В этой статье я хочу описать программу валидации XML с помощью Spring Framework. Наиболее очевидная область применения такой валидации — это программирование web-сервисов.

Валидация производится через преобразование XML-Java (unmarshalling) по соответствующей XSD-схеме. XML-файл считается прошедшим проверку, если преобразование XML в объект Java прошло успешно.

Проект компилируется в jar файл и запускается в командной строке. Для красоты прикручен Apache ANSI Printer, в котором можно задавать шрифт, цвет и выделение текста в cmd.

Исходный код доступен в GitHub по ссылке XmlProcessor.

1. Исходные файлы и схемы

В качестве входных данных определим 2 XML файла Address.xml и Client.xml.

   V001.000.00 
50 7 Sadovaya SPB Russia 123456

Далее определим XSD-схемы XmlValidator.xsd, ComplexTypes.xsd и SimpleTypes.xsd с
описанием контейнера CombinedType и объектов типа Address и Client:

     XSD structure   XML definition    
        The version     Address type    Client type         Apartment number    House number    Street name    City name    Country name    Postal index        The id    The name      
    V000.000.00   .7.9"/>   Int, 10 max      String, 50 max      Int, 4 max      Int, 3 max      String, 40 max      City, 40 max      Country, 30 max      Int, 10 max      

Обратите внимание на элемент в CombinedType схемы ComplexTypes.xsd. Он означает, что xml-файл должен содержать либо один элемент типа Address, либо один или несколько элементов типа Client.

2. Конфигурация Spring

В файле spring-config.xml находится описание используемых в проекте бинов Printer,
FileReader, Marshaller, XMLService. Помимо указанных бинов, определен фильтр расширений
FileNameExtensionFilter, чтобы рассматривать только xml-файлы.

        xml          com.xmlprocessor.types.CombinedType    xmlvalidator.xsd complextypes.xsd simpletypes.xsd        true           

3. Преобразование XML-Java

В точке входа приложения XmlProcessorDrv сначала считываем и проверяем аргументы
командной строки, затем через вызов методов класса Compositor создаем бины printer,
fileReader и xmlService. Далее считываем xml-файлы и выполняем валидацию файлов в
директории, указанной в CLI_OPTION_DIRECTORY.

Самое интересное происходит при вызове

xmlService.validate(xmlFiles)
 package com.xmlprocessor.main; import java.io.File; import java.util.List; import com.xmlprocessor.config.Compositor; import com.xmlprocessor.service.api.PrinterInt; import com.xmlprocessor.service.api.XmlServiceInt; import com.xmlprocessor.util.CommandLineArgs; public class XmlProcessorDrv < /** Name of the program */ private static final String PROG_NAME = XmlProcessorDrv.class.getSimpleName(); /** Version of the Program */ private static final String PROG_VERSION = "1.0 (XmlProcessor v1.000)"; /** Exit Status for OK. */ private static final int EXIT_STATUS_OK = 0; /** Exit Status for not OK. */ private static final int EXIT_STATUS_NOT_OK = -1; /** * Main entry point. * Evaluates command line args and validates provided xml files * * @param args * Command line arguments */ public static void main(String[] args) < // execution status int exitStatus; // get printer object PrinterInt printer = Compositor.getPrinter(); // read command line args CommandLineArgs cmdLineArgs = new CommandLineArgs(args); // Show version if (cmdLineArgs.hasOption(CommandLineArgs.CLI_OPTION_VERSION)) < printer.printf("%s v%s\n", PROG_NAME, PROG_VERSION); >// Show help if (cmdLineArgs.hasOption(CommandLineArgs.CLI_OPTION_HELP)) < cmdLineArgs.printHelp(PROG_NAME); >// Check if the directory name is passed in args if (!cmdLineArgs.hasOption(CommandLineArgs.CLI_OPTION_DIRECTORY)) < cmdLineArgs.printHelp(PROG_NAME); return; >String dir = cmdLineArgs.getOptionValue(CommandLineArgs.CLI_OPTION_DIRECTORY); printer.printf("\n%s %s","Folder with XML files: ", dir); List xmlFiles; XmlServiceInt xmlService = Compositor.getXmlService(); try < xmlFiles = Compositor.getFileReader().readFiles(dir); printer.bold("\n\nStart validating XML files:\n"); xmlService.validate(xmlFiles); exitStatus = EXIT_STATUS_OK; >catch (Exception ex) < printer.errorln("\n" + ex.getMessage()); exitStatus = EXIT_STATUS_NOT_OK; >System.exit(exitStatus); > // main > 

Код метода validate представлен ниже.

 . /** */ public void validate(List xmlFiles) throws Exception < int fileCount = xmlFiles.size(); File currentFile; FileInputStream fileInputStream = null; Source xmlFileSource; CombinedType combinedType; AddressType addressType; for (int count = 0; count < fileCount; count++) < currentFile = xmlFiles.get(count); printer.boldln("Current file: ").println(currentFile.getPath()); try < fileInputStream = new FileInputStream(currentFile); xmlSource = new StreamSource(fileInputStream); combinedType = (CombinedType)unmarshaller.unmarshal(xmlSource); printer.boldln("Xml file [" + currentFile.getName() + "] validation success!\n"); printer.boldln("Version: ").println(combinedType.getVersion()); addressType = combinedType.getAddress(); if (addressType != null) < printer.boldln("Address: ").println(addressType.toString()); >else if (combinedType.getClients() != null) < int i=0; for (ClientType client : combinedType.getClients()) < printer.boldln("Client").println("[" + ++i + "]" + client.toString()); >> > catch(Exception e) < printer.fatalln("Xml file [" + currentFile.getName() + "] validation error: \n" + e.getMessage()); >finally < if (fileInputStream != null) < fileInputStream.close(); >> > printer.boldln("Validating complete."); > 

Ключевое преобразование XML-Java или unmarshalling происходит в строке

combinedType = (CombinedType)unmarshaller.unmarshal(xmlSource); 

Как уже упоминалось, если удалось из XML получить java-объект типа CombinedType, то
XML признается корректным.

Unmarshaller-у должен быть заранее известен конечный объект преобразования. Для
этого с помощью JAXB создадим файлы AddressType.java, ClientType.java, CombinedType.java
В IDE Eclipse: правый клик по XSD -> Generate -> JAXB Classes…

 package com.xmlprocessor.types; import java.math.BigInteger; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; /** * 

Java class for AddressType complex type.

*/ @SuppressWarnings("restriction") @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "AddressType", propOrder = < "apartment", "street", "house", "city", "country", "index" >) public class AddressType < @XmlElement(name = "Apartment", required = true) protected Integer apartment; @XmlElement(name = "House", required = true) protected BigInteger house; @XmlElement(name = "Street", required = true) protected String street; @XmlElement(name = "City", required = true) protected String city; @XmlElement(name = "Country", required = true) protected String country; @XmlElement(name = "Index") protected BigInteger index; public Integer getApartment() < return apartment; >public void setApartment(Integer value) < this.apartment = value; >public String getStreet() < return street; >public void setStreet(String value) < this.street = value; >public BigInteger getHouse() < return house; >public void setHouse(BigInteger value) < this.house = value; >public String getCity() < return city; >public void setCity(String value) < this.city = value; >public String getCountry() < return country; >public void setCountry(String value) < this.country = value; >public BigInteger getIndex() < return index; >public void setIndex(BigInteger value) < this.index = value; >public boolean isSetIndex() < return (this.index!= null); >@Override public String toString() < StringBuilder sb = new StringBuilder(); sb.append("\nApartment#: " + apartment); sb.append("\nHouse#: " + house); sb.append("\nStreet: " + street); sb.append("\nCity: " + city); sb.append("\nCountry: " + country); if (this.isSetIndex()) < sb.append("\nIndex: " + index); >return sb.toString(); > >
 package com.xmlprocessor.types; import java.math.BigInteger; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; @SuppressWarnings("restriction") @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "ClientType", namespace = "http://www.tempuri.org/complextypes", propOrder = < "id", "name" >) public class ClientType < @XmlElement(name = "Id", required = true) protected BigInteger id; @XmlElement(name = "Name", required = true) protected String name; public BigInteger getId() < return id; >public void setId(BigInteger value) < this.id = value; >public String getName() < return name; >public void setName(String value) < this.name = value; >@Override public String toString() < StringBuilder sb = new StringBuilder(); sb.append("\nId: " + id); sb.append("\nName: " + name); return sb.toString(); >> 
 package com.xmlprocessor.types; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; /** * 

Java class for CombinedType complex type. */ @SuppressWarnings("restriction") @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "CombinedType", propOrder = < "version", "clients", "address" >) @XmlRootElement(name = "Combined", namespace = "http://www.tempuri.org/types") public class CombinedType < @XmlElement(name = "Version", required = true) protected String version; @XmlElement(name = "Client") protected Listclients; @XmlElement(name = "Address") protected AddressType address; public String getVersion() < return version; >public void setVersion(String value) < this.version = value; >public List getClients() < if (clients == null) < clients = new ArrayList(); > return this.clients; > public AddressType getAddress() < return address; >public void setAddress(AddressType value) < this.address = value; >>

4. Демонстрация работы программы

В проект включен файл Readme с описанием доступных опций и аргументов командной
строки:

 XmlProcessor v1.0 Usage: java -jar XmlProcessorDrv [-d ] [-h] [-v] -h,--help Display this help -v Version of the program -d Folder with XML files to be validated Example: java -jar xmlProcessor.jar --help -v -d "C:\\XmlSample" 

Для запуска проекта из cmd скомпилируем jar, вызвав Maven build package на pom.xml, и в
cmd введем вышеописанную команду

java -jar xmlProcessor.jar -h -v -d «C:\XmlSample»

Директория C:\XmlSample должна содержать один или несколько файлов вида Address.xml и
Client.xml. Файлы с расширением не xml будут проигнорированы.

Пример корректной работы программы:

Программа выдаст ошибку, если длина поля превышает установленный в SimpleTypes.xsd предел, имеется опечатка в имени узла, итд. Для примера допустим, что первый элемент адреса написан как AApartment:

   V001.000.00 
50 7 Sadovaya Saint Petersburg Russia 123456

В этом случае программа выдаст ошибку:

Источник

How to validate XML against XSD in Java

How to validate XML against XSD in Java

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Java XML Validation API can be used to validate XML against XSD in java program. javax.xml.validation.Validator class is used in this program to validate xml against xsd in java.

Validate XML against XSD

Validate XML against XSD java, java xml validation, xsd validator java

Here are the sample XSD and XML files used. Employee.xsd

Notice that above XSD contains two root element and namespace also, I have created two sample XML file from XSD using Eclipse. EmployeeRequest.xml

  Pankaj 29 Java Developer Male  

Here is the program that is used to validate all three XML files against the XSD. The validateXMLSchema method takes XSD and XML file as argument and return true if validation is successful or else returns false. XMLValidation.java

package com.journaldev.xml; import java.io.File; import java.io.IOException; import javax.xml.XMLConstants; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import org.xml.sax.SAXException; public class XMLValidation < public static void main(String[] args) < System.out.println("EmployeeRequest.xml validates against Employee.xsd? "+validateXMLSchema("Employee.xsd", "EmployeeRequest.xml")); System.out.println("EmployeeResponse.xml validates against Employee.xsd? "+validateXMLSchema("Employee.xsd", "EmployeeResponse.xml")); System.out.println("employee.xml validates against Employee.xsd? "+validateXMLSchema("Employee.xsd", "employee.xml")); >public static boolean validateXMLSchema(String xsdPath, String xmlPath) < try < SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = factory.newSchema(new File(xsdPath)); Validator validator = schema.newValidator(); validator.validate(new StreamSource(new File(xmlPath))); >catch (IOException | SAXException e) < System.out.println("Exception: "+e.getMessage()); return false; >return true; > > 
EmployeeRequest.xml validates against Employee.xsd? true EmployeeResponse.xml validates against Employee.xsd? true Exception: cvc-elt.1: Cannot find the declaration of element 'Employee'. employee.xml validates against Employee.xsd? false 

The benefit of using Java XML validation API is that we don’t need to parse the file and there is no third party APIs used.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases. Learn more about us

Источник

Оцените статью