如@robert-penridge所提到的,存在一种称为XMLv2引擎的东西。然而,在SAS中直接验证它是不可能的,因为XMLv2引擎不会根据xsd验证xml,并且它假定它是一个正确的XML...
有一种方法可以通过JAVA和SAS来实现(适用于SAS 9.3+,不确定早期版本)。
因此,您需要将此Java文件放在您可以通过SAS访问的某个位置。
Java代码(必须命名为
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;
} catch (SAXException e) {
System.out.println(xmlSource.getSystemId() + " is NOT valid reason:" + e);
return 1;
} catch (IOException e) {
return 2;
}
}
public static void main(String [ ] args){
XMLValidator validator=new XMLValidator(args[1],args[2]);
System.out.println(validator.validate());
}
}
当使用javac XMLValidator.java
进行编译时,请记住保存路径。
现在,您可以使用以下SAS代码验证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;
如果验证成功,此代码将返回0,如果验证失败,则返回1或2。
R
,而R
函数xmlSchemaValidate
可以根据模式验证XML,但我担心这需要在SAS安装中安装额外的R模块。 - Dirk Horsten