We’re working on an XML import routine and needed to first validate the incoming documents against an XML Schema. Since I wasn’t able to find a working example on the web I pieced together this UDF from the many posts on the subject.
- xmlPath
- A URI to the XML file to be validated. Required.
- noNamespaceXsdUri
- A URI to the XML Schema file to validate content that is not namespace qualified. Optional.
- namespaceXsdUri
- A list of whitespace delimited namespaces and XSD URI pairs to provide schemas for validating namespace qualified content. Optional.
- parseError
- An empty structure that is populated with details about the validation error, if any. This argument can be ommitted if all you want is the boolean result.
The URI parameters must be valid URLs and not OS file names. To facilitate this I’m also including a UDF, makeUriFromPath, that convers a fully-qualified OS file name to a true URI.
To use this UDF you must have the Xerces parser installed which can be downloaded here.
var parser = createObject("java","org.apache.xerces.parsers.SAXParser");
var err = structNew();
var k = "";
var success = true;
var eHandler = createObject(
"java",
"org.apache.xml.utils.DefaultErrorHandler");
var apFeat = "http://apache.org/xml/features/";
var apProp = "http://apache.org/xml/properties/";
eHandler.init();
if (structKeyExists(arguments, "parseError")) {
err = arguments.parseError;
}
try {
parser.setErrorHandler(eHandler);
parser.setFeature(
"http://xml.org/sax/features/validation",
true);
parser.setFeature(
apFeat & "validation/schema",
true);
parser.setFeature(
apFeat & "validation/schema-full-checking",
true);
if (structKeyExists(arguments, "noNamespaceXsdUri") and
arguments.noNamespaceXsdUri neq "") {
parser.setProperty(
apProp & "schema/external-noNamespaceSchemaLocation",
arguments.noNamespaceXsdUri
);
}
if (structKeyExists(arguments, "namespaceXsdUri") and
arguments.namespaceXsdUri neq "") {
parser.setProperty(
apProp & "schema/external-schemaLocation",
arguments.namespaceXsdUri
);
}
parser.parse(arguments.xmlPath);
} catch (Any ex) {
structAppend(err, ex, true);
success = false;
}
function makeUriFromPath(path) {
var uri = path;
// make all backslashes into slashes
uri = replace(uri, "", "/", "all");
if (left(uri,1) is "/") {
uri = right(uri, len(uri) - 1);
}
uri = "file:///" & uri;
return uri;
}
Valid: #xsdValidate(xmlUri, xsdUri, "", err)#
This UDF was put together primarily from information in Rob Rohan’s post on this cf-talk thread and from Massimo Foti’s UDF to validate an XML file against a DTD.
I’ll submit both of the above to cflib shortly.
Haha… a while ago I was trying to point someone down the xerces path on MM’s forums, but I could only write some sample code. Thanks for helping them out:
http://www.macromedia.com/cfusion/webforums/forum/messageview.cfm?catid=7&threadid=771531&forumid=1
Yes, that code is pretty much the same as the code I got from Rob’s cf-talk post. Found Rob’s first so I gave him credit, not sure which of you actually poseted first.
The reason that code didn’t actually work to give you a valid/invalid result is that it was using a DOMParser which wasn’t throwing any errors on invalid documents. Based on Massimo’s DTD validation UDF I switched it to a SAX parser with a default error handler and that did the trick.
Best regards,
Sam
Hello there,
Iwas browsing the web and found this blog. Some interesting quotes. Keep them coming!
Alice
weight loss meltrx success
Welcome Home Everyone Home
Cya
Max
Hi Guys
Thanks for taking the time posting. MSN have finally launch blogs, what was with the delay?
Virtual Office Canterbury
Cya
Bruce