Sidebar

XML Validation against XSD Schema

0 votes
2.3K views
asked Feb 19, 2018 by aritra-k-6337 (400 points)
Hi Team,

Can someone help me with a validator script which can perform the XML Validation againsta a standard XSD, so that I can apply that as a step in my conditional mapping.

I have checked in google and we found that we have an API in Java (JAXP.jar) which can validate an XML with an XSD file. I have tried to import this, but unable to get this thing working. It would be great if someine guide/help me with this.

Regards,

Aritra

1 Answer

0 votes

Here is an example of using the javax.xml.validation libraries inside of java to validate using a .xsd file:

try {
   // get new factory instance
   var factory = javax.xml.validation.SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
   
   // in this case we feed the .xsd file from a system variable named 'Employee.xsd'.  This could be changed to a file or some other method to get the .xsd loaded
   var schema = factory.newSchema(new javax.xml.transform.stream.StreamSource(new java.io.ByteArrayInputStream(qie.getVariable('Employee.xsd').getBytes())));
   
   // Now we validate the current message using the schema validator created with the .xsd
   var validator = schema.newValidator();
   validator.validate(new javax.xml.transform.stream.StreamSource(new java.io.ByteArrayInputStream(source.getBytes())));
   
   // log out the results of the validation
   qie.warn('Validation Passed.  Happy Days');
} catch (err) {
   qie.warn('Validation Failed: ' + err);
}

Here is a sample XML that will pass validation.

<?xml version="1.0" encoding="UTF-8"?>
<empns:empRequest xmlns:empns="https://www.journaldev.com/Employee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.journaldev.com/Employee Employee.xsd ">
   <empns:id>5</empns:id>
</empns:empRequest>

Here is a sample xml that will fail validation

<?xml version="1.0"?>
<Employee>
   <name>Pankaj</name>
   <age>29</age>
   <role>Java Developer</role>
   <gender>Male</gender>
</Employee>

Here is the XSD File

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
targetNamespace="https://www.journaldev.com/Employee" 
xmlns:empns="https://www.journaldev.com/Employee" elementFormDefault="qualified">

    <element name="empRequest" type="empns:empRequest"></element>
    
    <element name="empResponse" type="empns:empResponse"></element>

    <complexType name="empRequest">
        <sequence>
            <element name="id" type="int"></element>
        </sequence>
    </complexType>
    
    <complexType name="empResponse">
        <sequence>
            <element name="id" type="int"></element>
            <element name="role" type="string"></element>
            <element name="fullName" type="string"></element>
        </sequence>
    </complexType>
</schema>

answered Feb 20, 2018 by ben-s-7515 (12,640 points)
edited Feb 20, 2018 by ben-s-7515
commented Feb 21, 2018 by aritra-k-6337 (400 points)
Thank you for sharing the details. I have created a validation step and update the script. However, I am getting the below error:

[path=1-2] - Validation Failed: JavaException: org.xml.sax.SAXParseException: cvc-elt.1.a: Cannot find the declaration of element 'Request'.

Could you please let me know if I need to make any changes in the script or in the XML. Also we cannot modify the XSD as this is set by the client.

XSD file:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ChaseRequestConfigurable" version="1.0.0.2" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:simpleType name="guid">
    <xs:restriction base="xs:string">
        <xs:pattern value="([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})|(\{[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\})"/>
    </xs:restriction>
    </xs:simpleType>
  <xs:simpleType name="shortDate">
    <xs:restriction base="xs:string">
      <xs:pattern value="(\s+)?(((0?[13578]|10|12)(\/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[01]?))(\/)((189)(\d{1})|(19)(\d{2})|(20)([0-3])(\d{1})))|((0?[469]|11)(\/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[0]?))(\/)((189)(\d{1})|(19)(\d{2})|(20)([0-3])(\d{1})))|((0?[2])(\/)(([1-9])|(0[1-9])|([12])([0-9]?))(\/)((189)(\d{1})|(19)(\d{2})|(20)([0-3])(\d{1}))))(\s+)?"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="requiredString">
    <xs:restriction base="xs:token">
      <xs:minLength value ="1"/>
      <xs:maxLength value="80"/>
      <xs:pattern value="&lt;!\[CDATA\[.*\]\]&gt;|.*"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="number">
    <xs:restriction base="xs:string">
      <xs:whiteSpace value="collapse"/>
      <xs:minLength value="1"/>
      <xs:pattern value="[\d]*"/>
    </xs:restriction>
  </xs:simpleType>
    <xs:complexType name="flexContents">
      <xs:sequence>
    <xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
    <xs:group name="baseGroup">
        <xs:all>
            <xs:element name="PatientId" type="xs:string" minOccurs="0" maxOccurs="1" />
            <xs:element name="LastName" type="requiredString" minOccurs="1" maxOccurs="1" />
            <xs:element name="FirstName" type="requiredString" minOccurs="1" maxOccurs="1" />
            <xs:element name="Gender" type="requiredString" minOccurs="1" maxOccurs="1" />
            <xs:element name="DOB" type="shortDate" minOccurs="1" maxOccurs="1" />
            <xs:element name="Zip" minOccurs="1" maxOccurs="1">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
        <xs:pattern value="(\s+)?([0-9]{1,5}-?([0-9]{4})?)(\s+)?"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="PatientConsent" type="xs:string" minOccurs="0" maxOccurs="1" />
            <xs:element name="Phone" type="xs:string" minOccurs="0" maxOccurs="1" />
            <xs:element name="SSN" type="xs:string" minOccurs="0" maxOccurs="1" />
            <xs:element name="City" type="xs:string" minOccurs="0" maxOccurs="1" />
            <xs:element name="State" type="xs:string" minOccurs="0" maxOccurs="1" />
            <xs:element name="VariableTags" type="flexContents" minOccurs="0" maxOccurs="1" />
        </xs:all>
    </xs:group>
    <xs:group name="idGroup">
        <xs:choice>
            <xs:element name="UniqueClientId" type="xs:int" minOccurs="1" maxOccurs="1" />
            <xs:element name="PracticeId" type="xs:int" minOccurs="1" maxOccurs="1" />
        </xs:choice>
    </xs:group>
    <xs:complexType name="patientType">
        <xs:group ref="baseGroup" minOccurs="1" maxOccurs="1" />
    </xs:complexType>
    <xs:element name="ChaseRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Vendor" minOccurs="1" maxOccurs="1">
                    <xs:complexType>
                        <xs:attribute name="id" type="guid" />
                    </xs:complexType>
                </xs:element>
                <xs:element name="Request" minOccurs="1" maxOccurs="1">
                    <xs:complexType>
                        <xs:attribute name="id" type="guid" />
                    </xs:complexType>
                </xs:element>
                <xs:element name="Chases" minOccurs="1" maxOccurs="1">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Chase" minOccurs="1" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:group ref="idGroup" minOccurs="1" maxOccurs="1" />
                                        <xs:element name="AccountId" type="xs:string" minOccurs="0" maxOccurs="1" />
                                        <xs:element name="RequestingCompany" type="xs:string" minOccurs="0" maxOccurs="1" />
                                        <xs:element name="PatientData" type="patientType" minOccurs="1" maxOccurs="1" />
                                        <xs:element name="DateOfServiceRange" minOccurs="1" maxOccurs="1">
                                            <xs:complexType>
                                                <xs:sequence>
                                                    <xs:element name="StartDate" type="shortDate" minOccurs="1" />
                                                    <xs:element name="EndDate" type="shortDate" minOccurs="1" />
                                                </xs:sequence>
                                            </xs:complexType>
                                        </xs:element>
                                    </xs:sequence>
                                    <xs:attribute name="id" type="xs:long" use="required"/>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="dtGenerated" type="xs:string" />
        </xs:complexType>
    </xs:element>
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
        <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element ref="ChaseRequest" />
            </xs:choice>
        </xs:complexType>
    </xs:element>
</xs:schema>

XML file:
<?xml version="1.0" encoding="utf-8"?>
<ChaseRequest dtGenerated="Wednesday, February 21,2018 00:54:48 AM">
<Vendor id="0CAC1CC6-E071-48F4-9120-8EE4B0F684BB" />
<Request id="7BF380FC-6900-613C-3AFE-6EE4468057FF"  />
<Chases>   
    <Chase id="172515210">
        <UniqueClientId><![CDATA[1011]]></UniqueClientId>
        <AccountId></AccountId>
        <RequestingCompany>CTS</RequestingCompany>
        <PatientData>
            <LastName>Abbott</LastName>
            <FirstName>Leroy</FirstName>
            <Gender>M</Gender>
            <DOB>02/19/1927</DOB>
            <Zip>27511</Zip>
            <City>Raleigh</City>
            <State>NC</State>
            <PatientConsent></PatientConsent>
            <SSN>3671</SSN>
            <Phone>9195551560</Phone>
        </PatientData>
        <DateOfServiceRange>
            <StartDate>01/21/2018</StartDate>
            <EndDate>02/21/2018</EndDate>
        </DateOfServiceRange>
    </Chase>
</Chases>
</ChaseRequest>

Regards,
Aritra
commented Feb 21, 2018 by ben-s-7515 (12,640 points)
When I test the given XML with the given XSD it passes validation with the original script provided.  Make sure to save the XSD as a system variable, and make sure to reference that system variable in the script.  The assumption is that the message is the XML file.
...