This post shows how to validate an XML file against multiple XSDs in Kotlin wherein one XSD is included in another XSD file.
Requirements
We used the following items for this post.
- Java JDK 14
- IntelliJ IDEA 2020.3
- Kotlin 1.3.72
Our Multiple XML Schemas In XSD files
For this post, we use two XML schemas in separate XSD files. One of them being the main XML schema called myschema.xsd, while the other is a dependent XSD XML schema.
The dependent XSD file, my-other-schema.xsd, has the following contents. It defines the OtherInfo element, which has two string elements city and country.
1 2 3 4 5 6 7 8 9 | <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:complexType name="OtherInfo"> <xs:sequence> <xs:element name="city" type="xs:string" minOccurs="0" /> <xs:element name="country" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:schema> |
To use (or reuse) the OtherInfo element in another XSD file to validate XMLs, we use the <xs:include schemaLocation="my-other-schema.xsd"/>, as shown and highlighted below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:include schemaLocation="my-other-schema.xsd"/> <xs:element name="names"> <xs:complexType> <xs:sequence> <xs:element name="name" maxOccurs="unbounded" type="xs:string"/> <xs:element name="otherInfo" type="OtherInfo"/> </xs:sequence> </xs:complexType> <xs:unique name="uniqueName"> <xs:selector xpath="name"/> <xs:field xpath="."/> </xs:unique> </xs:element> </xs:schema> |
Note on line 3; we included the dependent XSD in myschema.xsd. These files must be in the same directory. In this post, the XSD and the test XML files are all in the project’s resources folder.
XML to Validate Against Multiple XSDs
Then, we craft an XML file to validate against our XSDs files. The XML file contains three names and an OtherInfo element. Note that the name elements have to be unique because we use the main XSD file’s unique constraint.
1 2 3 4 5 6 7 8 9 10 | <?xml version="1.0" encoding="UTF-8"?> <names xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <name>Manny Monday</name> <name>Armando Aragon</name> <name>Berting Labra</name> <otherInfo> <city>Makati</city> <country>Philippines</country> </otherInfo> </names> |
Kotlin Codes
Next, we write our main Kotlin codes similar to the following codes to validate XML Against Multiple XSDs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | package com.turreta.kotlin.xml import javax.xml.validation.SchemaFactory import javax.xml.transform.stream.StreamSource import java.io.File import org.xml.sax.SAXException import java.nio.file.Paths import java.nio.file.Path class MyClass { } fun main(args : Array<String>) { val factory: SchemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema") val mySchemaPath: Path = Paths.get(MyClass::class.java.getResource("/myschema.xsd").toURI()) val schemaLocation = File(mySchemaPath.toString()) val schema = factory.newSchema(schemaLocation) val validator = schema.newValidator() val mySampleXMLPath: Path = Paths.get(MyClass::class.java.getResource("/myxml-test.xml").toURI()) val source = StreamSource(mySampleXMLPath.toString()) println("Validation Starts now!") val start = System.currentTimeMillis() try { validator.validate(source) println(" XML is valid.") } catch (ex: SAXException) { println(" XML not valid because " + ex.message) } println("Validation complete!") println("Time (ms): " + (System.currentTimeMillis() - start)) } |
DEMO: Validate XML Sample Against XSDs
When we run the codes, we get the following output on the console window in the IDE.
The Kotlin codes are not ideal, but they show how to validate an XML against multiple XSDs. When referencing files in the resources folder, we need to prepend the file name with “/”; otherwise, the Kotlin codes will return NullPointerException. For example, /myschema.xsd instead of just myschema.xsd.
That is all for now. Thank you!