How to Validate XML against an XML Schema using Groovy

Document created by harvey_melfi Employee on Mar 30, 2016Last modified by Adam Arrowsmith on Jan 21, 2017
Version 4Show Document
  • View in full screen mode

This article describes how to validate an XML document against an XML Schema Definition (XSD) file.

 

 

Use Case

You want to validate an XML document against an external XML Schema Definition (XSD) document to perform validations beyond what  can be performed using the Cleanse or Business Rules shapes.

 

Approach

Use Groovy script within a Data Process shape to retrieve the external XSD and validate the current document against it.

  1. Use a Data Process shape with a custom scripting step to reference the external XSD and and validate the current document data against it. The sample script below provides  three options for referencing the XSD:
    1. From a URL
    2. From a local file
    3. From a dynamic process property. This option can be used if the XSD is read into the process along with the source data. See the Implementation section below.
  2. The script sets a dynamic document property with the validation result and error message. Note: if the document is invalid, it will NOT generate a process or document exception.
    1. If the document is valid, isValid="true"
    2. If the document is invalid, isValid="false" and validationError=<validation exception message>
  3. Utilize a Decision shape to inspect the isValid property and route the document accordingly.

 

Implementation

The following examples uses "option 2" to read the XSD from a local file. This assumes you have a local Atom installed.

 

  1. Download the attached test files and extract to a local directory.
  2. Create an integration process that gets the XML file using the Disk Connector.
  3. Add a Data Process shape with a Custom Scripting step. Replace the default custom script with the following.
  4. Specify the local directory path for "Option 2" (line 31). Remove the code for the other two options.

 

import java.util.Properties;
import java.io.InputStream;

import com.boomi.execution.ExecutionUtil;  // If use OPTION 3

import org.xml.sax.SAXException;

import javax.xml.XMLConstants;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

// Load a WXS schema, represented by a Schema instance
// BEGIN CHOOSE ONE //

// OPTION 1: URL
URL schemaFile = new URL("http://www.someurl.com/schemas/books.xsd");

// OPTION 2: Local File
Source schemaFile = new StreamSource(new File("C:/Test/In/books.xsd"));

// OPTION 3: Dynamic Process Property
String schemaDPP = ExecutionUtil.getDynamicProcessProperty("XSD_DATA");
Source schemaFile = new StreamSource(new StringReader(schemaDPP));

// END CHOOSE ONE //

for (int i = 0; i < dataContext.getDataCount(); i++) {
    InputStream is = dataContext.getStream(i);
    Properties props = dataContext.getProperties(i);

    // create a Source for the xml document to be validated
    Source xmlFile = new StreamSource(is);


    // Create a SchemaFactory capable of understanding WXS schemas
    SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = factory.newSchema(schemaFile);

    // Create a Validator instance, which can be used to validate an instance document
    Validator validator = schema.newValidator();

    // Validate the xml document
    try {

        validator.validate(xmlFile);
        props.setProperty("document.dynamic.userdefined.isValid", "true"); 

    } catch (SAXException e) {

        // instance document is invalid!
        props.setProperty("document.dynamic.userdefined.isValid", "false"); 
        props.setProperty("document.dynamic.userdefined.validationError", e.getMessage()); 

    }

    // Reset document InputStream to pass original xml document to next shape
    is.reset();
    dataContext.storeStream(is, props);
}

 

Integration Process

 

 

This process:

  1. Reads the books.xml file from the local directory in the Start shape.
  2. Uses the Data Process Custom Script to validate the XML file against the books.xsd XSD file from the local directory.
  3. Uses a Decision shape to determine whether the document w as valid by comparing the isValid dynamic document property equals "true".
  4. Processes the document accordingly. For example, if invalid use an Exception shape to report the problem:

 

    

 

Usage Considerations

  • The script and process assumes the XSD will apply to all documents read into the process. If your scenario requires different XSDs for different types of document you will need to make changes to either execute documents individually or parameterize accordingly.
  • You may wish to add additional error handling in the script to more gracefully capture and handle configuration issues like missing or invalid XSD files.
10 people found this helpful

Outcomes