Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate output XML with XML Schema (xsd)

I create simple XML file in my SAS program:

data _null_;
   file "C:\persons.xml";
   put "<?xml version=""1.0"" encoding=""UTF-8""?>";
   put "<Person>";
   put "<Name>John</Name>";
   put "<Age>32</Age>";
   put "</Person>";
run;

And I have XML Schema (xsd file). I want to validate my file with schema and put error if the file does not match the shema. Is it possible?

Thanks in advance!

like image 596
PierreVanStulov Avatar asked Nov 03 '15 08:11

PierreVanStulov


People also ask

Can we validate XML documents against a schema?

You can validate your XML documents against XML schemas only; validation against DTDs is not supported. However, although you cannot validate against DTDs, you can insert documents that contain a DOCTYPE or that refer to DTDs.

How do I validate an XML document against an XSD schema?

XML documents can be validated against an XML schema definition language (XSD) schema in an XmlSchemaSet. XML documents are validated by the Create method of the XmlReader class. To validate an XML document, construct an XmlReaderSettings object that contains an XML schema definition language (XSD) schema with which to validate the XML document.

How do I read and write XML schemas?

Read and write XML Schema definition language (XSD) schemas from files or other sources in .NET, using the Schema Object Model (SOM) API. You can use extension methods from the System.Xml.Schema namespace to validate an XML tree against an XML Schema Definition Language (XSD) file.

How do I validate an XML file in Java?

Validating XML Documents. XML documents are validated by the Create method of the XmlReader class. To validate an XML document, construct an XmlReaderSettings object that contains an XML schema definition language (XSD) schema with which to validate the XML document.

How to get XSD error messages from an XML file?

Finally, call a validate() method on a validator object by inputting XML file. We should also create ErrorHandlerby an overriding warning(), error() and fatal() methods and pass this to setErrorHandler() on validator, which captures xsd messages. When you run this example, it returns all XSD error, fatal and warning messages in a list. Output:


1 Answers

As @robert-penridge mentioned, there exist something called XMLv2 engine. However, it is not possible to validate it directly in SAS, as XMLv2 engine does not validate xml against xsd, and it assumes it is a proper XML...

There is a way to do it with JAVA and SAS (works for SAS 9.3+, not sure about earlier versions). So, you need to place this java file somewhere where you can reach it through SAS.

Java Code (has to be named XMLValidator.java):

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;

class XMLValidator{

    File schemaFile;
    File xmlFile;
    XMLValidator(String pathXSD, String pathXML){
        this.schemaFile = new File(pathXSD);
    this.xmlFile=new File(pathXML);
    }

public int validate(){
    Source xmlSource = new StreamSource(xmlFile);
    SchemaFactory schemaFactory = SchemaFactory
        .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    try {
        Schema schema = schemaFactory.newSchema(schemaFile);
        Validator validator = schema.newValidator();
        validator.validate(xmlSource);
        return 0; // schema is valid
        } catch (SAXException e) {
        System.out.println(xmlSource.getSystemId() + " is NOT valid reason:" + e);
        return 1; // schema is not valid
    } catch (IOException e) {
        return 2;
    }
        }
    public static void main(String [ ] args){
        XMLValidator validator=new XMLValidator(args[1],args[2]);
        System.out.println(validator.validate());
    }
}

When compiled (with javac XMLValidator.java), remember the path where you saved it.

Now you can use the following SAS Code to validate XML:

%macro init_classpath_update;
  DATA _null_;
      LENGTH  path_separator $ 2
              orig_classpath $ 32767;

      DECLARE JavaObj f("java.io.File", "");
      f.getStaticStringField("pathSeparator", path_separator);

      orig_classpath = STRIP(SYSGET("CLASSPATH"));

      IF _ERROR_ = 1 OR LENGTH(orig_classpath) = 0 THEN DO;
      PUT "NOTE: Ignore any messages from the next statement(s)";
          orig_classpath = "";
    END;

      CALL SYMPUTX('CP_orig_classpath', STRIP(orig_classpath), 'GLOBAL');
      CALL SYMPUTX('CP_path_separator', COMPRESS(path_separator), 'GLOBAL');
  RUN;
%mend;

%macro add_to_classpath(cp_addition);
  DATA _null_;
      LENGTH  current_classpath $ 32767
              new_classpath $ 32767;

      current_classpath = STRIP(SYSGET("CLASSPATH"));

      IF _ERROR_ = 1 OR LENGTH(current_classpath) = 0 THEN DO;
      PUT "NOTE: Ignore any messages from the nearby statement(s)";
          new_classpath = "&cp_addition";
    END;
      ELSE DO;
          new_classpath = COMPRESS(current_classpath) || "&CP_path_separator" || "&cp_addition";
    END;

      CALL SYMPUTX('CP_new_classpath', STRIP(new_classpath), 'GLOBAL');
  RUN;

  %PUT NOTE: Setting Java classpath to &CP_new_classpath;
  OPTIONS SET=CLASSPATH "&CP_new_classpath";
%mend;

%macro reset_classpath;
  %PUT NOTE: Setting Java classpath back to its original state: &CP_orig_classpath;
  OPTIONS SET=CLASSPATH "&CP_orig_classpath";
%mend;

proc javainfo;
run;

%init_classpath_update;
%add_to_classpath(<path_where_you_saved_your_compiled_XMLValidator_file>/.);

data _null_;
     length rtn_val 8;
   declare javaobj xsdPath("java/lang/String","<path_to_your_xsd_file_as_absolute_path>");
   declare javaobj xmlPath("java/lang/String","<path_to_your_xml_file_as_absolute_path>");
   declare javaobj xmlValidator("XMLValidator",xsdPath,xmlPath);
   rc = xmlValidator.callIntMethod("validate",rtn_val);
   xsdPath.delete();
   xmlPath.delete();
   xmlValidator.delete();
  putlog rc= rtn_val=;
run;

This code will return 0 if the validation is successful, and 1 or 2 if the validation has failed.

like image 178
Sale Avatar answered Nov 04 '22 23:11

Sale