Validate xml with xsd in java

Validating XSD against W3C XML Schema Definition

I am generating some XML Schemas and would like to ensure that our generator is creating valid XML Schema documents (Not XML). I was trying to come up with the code to validate the XML Schema document, but failing miserably. I didn’t think it would be this complex.

 private void validateXsd( String xsdAsString ) < try < SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); factory.setNamespaceAware(true); factory.setFeature( "http://apache.org/xml/features/validation/schema", true ); SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI ); URL xmlSchemaXSD = this.getClass().getClassLoader().getResource( "com/metamodel/xsd/XMLSchema.xsd" ); URL xmlSchemaDTD = this.getClass().getClassLoader().getResource( "com/metamodel/xsd/XMLSchema.dtd" ); URL xmlSchemaDataTypes = this.getClass().getClassLoader().getResource( "com/metamodel/xsd/datatypes.dtd" ); // requires that XMLSchema.dtd and datatypes.dtd are present in the same directory with the XMLSchema.xsd. factory.setSchema( schemaFactory.newSchema( xmlSchemaXSD ) ); SAXParser parser = factory.newSAXParser(); // parser.setProperty( "http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema" ); XMLReader reader = parser.getXMLReader(); reader.setErrorHandler( new SimpleErrorHandler() ); reader.parse( new InputSource( IOUtils.toInputStream( xsdAsString ) ) ); >catch( SAXParseException e ) < e.printStackTrace( System.err ); >catch ( ParserConfigurationException e ) < e.printStackTrace( System.err ); >catch ( SAXException e ) < e.printStackTrace( System.err ); >catch ( IOException e ) < e.printStackTrace( System.err ); >> 
org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'jar:file:/r:/as4ot/lib/metamodel.jar!/com/metamodel/xsd/XMLSchema.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not . at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:236) at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:172) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:382) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:316) at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(XSDHandler.java:2245) at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getSchema(XSDHandler.java:1590) at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:438) at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:556) at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:523) at com.sun.org.apache.xerces.internal.jaxp.validation.xs.SchemaFactoryImpl.newSchema(SchemaFactoryImpl.java:206) at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:489) at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:521) 
  • Load the XMLSchema.xsd from inside the jar so that it is neatly packaged with the code.
  • Get past the next error regarding xml:lang.

Hopefully I’m not asking too much!

Источник

Валидация 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   .8.8"/>   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.

Читайте также:  Прекращение выполнения скрипта php

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 признается корректным.

Читайте также:  Html img src class img

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

Источник

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