Showing posts with label JAXB. Show all posts
Showing posts with label JAXB. Show all posts

Tuesday, November 6, 2018

XML Schema

Objectives


Today I'm going to introduce you in subject of creating, visualization and using XSD. XML Schema was created by W3C for creating XML structure definition. This is a kind of contract which could be used in many solutions. One of the best usages is creating data model in WSDL (Web service contract)

Below is personal data's XSD structure which contains simple and complex types. There are diverse types of restrictions:

  • simple:  minOccurs, maxOccurs
  • complex: <xsd:restriction base="xsd:string"> 

There is also example of inheritance:  <xsd:extension base="as:document">

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:as="https://www.linkedin.com/in/artur-scigajlo-9144092/"
            targetNamespace="https://www.linkedin.com/in/artur-scigajlo-9144092/"
            xmlns:iso639-2="http://lcweb.loc.gov/standards/iso639-2/"
            elementFormDefault="qualified">
           
    <xsd:import namespace="http://lcweb.loc.gov/standards/iso639-2/"  schemaLocation="http://files.dnb.de/standards/xmetadiss/iso639-2.xsd"/>
               
               
   <xsd:complexType name="personalData">
        <xsd:sequence>
            <xsd:element name="workerId" type="xsd:string" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="worker" type="as:worker" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="partA" type="as:documentPartA" minOccurs="1" maxOccurs="unbounded"/>
            <xsd:element name="partB" type="as:documentPartB" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
             
  <xsd:complexType name="worker">
        <xsd:sequence>
            <xsd:element name="lastName" type="xsd:string" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="firstName" type="xsd:string" minOccurs="1" maxOccurs="1"/>
            <xsd:choice>
                <xsd:element name="personId">
                   <xsd:simpleType>
                    <xsd:restriction base="xsd:string">
                      <xsd:minLength value="10"/>
                      <xsd:maxLength value="26"/>
                    </xsd:restriction>
                  </xsd:simpleType>
                </xsd:element>
                <xsd:element name="otherTypeOfDocument">
                    <xsd:complexType>
                        <xsd:sequence>
                          <xsd:element name="type" type="xsd:string" minOccurs="1" maxOccurs="1"/>
                          <xsd:element name="number" type="xsd:string" minOccurs="1" maxOccurs="1"/>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:choice>
        </xsd:sequence>
    </xsd:complexType>
   
        <xsd:complexType name="document">
            <xsd:sequence>
                <xsd:element name="documentId" type="xsd:string" minOccurs="1" maxOccurs="1"/>
                <xsd:element name="title" type="as:title" minOccurs="0" maxOccurs="1"/>
                <xsd:element name="createdDate" type="xsd:date" minOccurs="1" maxOccurs="1"/>
                <xsd:element name="documentType" type="as:documentType" minOccurs="0" maxOccurs="1"/>
            </xsd:sequence>
    </xsd:complexType>
   
       <xsd:complexType name="title">
        <xsd:simpleContent>
            <xsd:extension base="xsd:string">
                <xsd:attribute name="language" type="iso639-2:RegisteredCodeType" use="optional"/>
            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>
   
      <xsd:complexType name="documentType">
        <xsd:sequence>
            <xsd:element name="type" minOccurs="1" maxOccurs="1">
              <xsd:simpleType>
                <xsd:restriction base="xsd:string">
                  <xsd:enumeration value="driverLicence"/>
                  <xsd:enumeration value="passport"/>
                  <xsd:enumeration value="insuranceNo"/>
                  <xsd:enumeration value="other"/>
                </xsd:restriction>
              </xsd:simpleType>
            </xsd:element>
            <xsd:element name="numer" type="xsd:string" minOccurs="1" maxOccurs="1"/>
        </xsd:sequence>
      </xsd:complexType>
   
    <xsd:complexType name="documentPartA">
        <xsd:complexContent>
            <xsd:extension base="as:document">
                <xsd:attribute name="subType" use="required">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                          <xsd:pattern value="^[ABC]\d{2}$"/>
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:attribute>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>
   
    <xsd:complexType name="documentPartB">
        <xsd:complexContent>
            <xsd:extension base="as:document">
                <xsd:attribute name="subType" use="required">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                          <xsd:pattern value="^[XYZ]\d{2}$"/>
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:attribute>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>   

</xsd:schema>




Data model visualization

There are existing useful applications to help creating XSD. Some of them have a plugins to generate visualization diagrams. Below is our schema's diagram.





Genarating XML file base on XSD Schema


I created project in Netbeans.





I imported XSD and generated java classes automatically.







We can see the generated classes





The main class is used to generate XML file









Below is java class

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package artur.scigajlo;

import artur.scigajlo.personalData.DocumentPartA;
import artur.scigajlo.personalData.DocumentType;
import artur.scigajlo.personalData.PersonalData;
import artur.scigajlo.personalData.Title;
import artur.scigajlo.personalData.Worker;
import artur.scigajlo.personalData.Worker.OtherTypeOfDocument;
import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;

/**
 *
 * @author a.scigajlo
 */
public class PersonalDataProject {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws PropertyException, JAXBException {
              PersonalData ao = new PersonalData();
        ao.setWorkerId("worker_01");
     
        Worker worker = new Worker();
        worker.setFirstName("Jon");
        worker.setLastName("Black");
     
        OtherTypeOfDocument otherDoc = new OtherTypeOfDocument();
        otherDoc.setNumber("AAA123456");
        otherDoc.setType("otherPersonId"); 
        worker.setOtherTypeOfDocument(otherDoc);     
     
        ao.setWorker(worker);
     
     
        DocumentPartA docA1 = new DocumentPartA();
        docA1.setCreatedDate(XMLGregorianCalendarImpl.createDate(2018,3,4,0));
        docA1.setDocumentId("docID-714");
     
        Title t1 = new Title();
        t1.setLanguage("pol");
        t1.setValue("hello.pdf");
        docA1.setTitle(t1);
     
        DocumentType dt1 = new DocumentType();
        dt1.setNumer("AEC12");
        dt1.setType("driverLicence");
        docA1.setDocumentType(dt1);
     
        ao.getPartA().add(docA1);
     
        DocumentPartA docA2 = new DocumentPartA();
        docA2.setCreatedDate(XMLGregorianCalendarImpl.createDate(2018,5,14,0));
        docA2.setDocumentId("annexID-318");
     
        Title t2 = new Title();
        t2.setLanguage("pol");
        t2.setValue("test.pdf");
        docA2.setTitle(t2);
     
        DocumentType dt2 = new DocumentType();
        dt2.setNumer("AEC12");
        dt2.setType("driverLicence");
        docA2.setDocumentType(dt2);
     
        ao.getPartA().add(docA2);
         
        JAXBContext jaxbContext = JAXBContext.newInstance(PersonalData.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
     
     
        //ZAPIS DO PLIKU
        jaxbMarshaller.marshal(ao, new File("c:\\tmp\\PersonalData.xml"));
    }
 
}


Finally we get XML file