Although Natural provides (very basic) functionality to parse and load an XML file, I could not find a way to validate XML against a schema. So I wrote a small Java program that does the validation and can be called from Natural (on Linux) via a User Exit.
Here is the Natural code for subprogram XMLVALID. It validates an XML file against a given schema using User Exit USR1052N (call a shell command) redirecting the output to a temp file. If an error occurred it reads the temp file and returns the error message. It uses quite a few hard coded paths you may need to change on your system.
DEFINE DATA
*
PARAMETER USING XMLVALP
*
LOCAL USING XMLVALC
*
LOCAL
01 USR1052L
02 OS-COMMAND (A253)
02 RESPONSE (I04)
*
01 #TEMPFILE (A) DYNAMIC
*
01 #WORK (A1000)
*
01 #DEFAULT-SCHEMA-PATH (A) DYNAMIC CONST <'/home/XML/'>
01 #INDEX (N4)
*
END-DEFINE
*
RESET XMLVALP-DEFAULT
*
EXAMINE FULL XML-SCHEMA FOR '/' GIVING POSITION IN #INDEX
IF #INDEX LE 0
COMPRESS #DEFAULT-SCHEMA-PATH XML-SCHEMA INTO XML-SCHEMA LEAVING NO
END-IF
*
COMPRESS '/tmp/XML-Validation-' *DATN '-' *TIMN '.txt' INTO #TEMPFILE LEAVING NO
COMPRESS '/usr/bin/java -cp' #DEFAULT-SCHEMA-PATH 'XMLValidator' XML-FILE XML-SCHEMA '>' #TEMPFILE INTO OS-COMMAND
*
CALLNAT 'USR1052N' USR1052L
XMLVALP.XML-RESULT := RESPONSE
*
IF XMLVALP.XML-RESULT NE VALID-XML
DEFINE WORK FILE 1 #TEMPFILE TYPE 'ASCII'
READ WORK 1 #WORK
COMPRESS XML-ERROR #WORK INTO XMLVALP.XML-ERROR
END-WORK
CLOSE WORK 1
END-IF
*
COMPRESS 'rm' #TEMPFILE INTO OS-COMMAND
CALLNAT 'USR1052N' USR1052L
*
END
The Java validator is pretty straightforward:
-
package xml;
-
-
import java.io.File;
-
import java.io.IOException;
-
-
import javax.xml.XMLConstants;
-
import javax.xml.parsers.DocumentBuilder;
-
import javax.xml.parsers.DocumentBuilderFactory;
-
import javax.xml.transform.dom.DOMSource;
-
import javax.xml.validation.Schema;
-
import javax.xml.validation.SchemaFactory;
-
import javax.xml.validation.Validator;
-
-
import org.w3c.dom.Document;
-
import org.xml.sax.SAXParseException;
-
-
public class XMLValidator
-
{
-
private final static int INVALID_PARAMETERS = 1;
-
private final static int INVALID_XML = 2;
-
private final static int INVALID_FILE = 3;
-
private final static int ANY_ERROR = 4;
-
-
{
-
if (args.length != 2)
-
{
-
}
-
-
-
try
-
{
-
validateXml(xmlFile, xsdFile);
-
}
-
{
-
}
-
}
-
-
{
-
// create a factory that understands namespaces and validates the XML input
-
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-
factory.setNamespaceAware(true);
-
-
try
-
{
-
// read the XML file
-
DocumentBuilder builder = factory.newDocumentBuilder();
-
-
// create a SchemaFactory capable of understanding schemas
-
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-
-
// load the schema
-
-
// validate the XML file
-
Validator validator = schema.newValidator();
-
validator.validate(new DOMSource(mDoc));
-
}
-
catch (SAXParseException spe)
-
{
-
// error generated by the parser
-
System.out.println("Parser error: URI " + spe.getSystemId() + ", Line " + spe.getLineNumber() + ", Message: " + spe.getMessage());
-
}
-
{
-
}
-
}
-
}



