UDF to validate XML against XSD in CFMX

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.

Easily work with Horizontal and Vertical content layouts

Recently we ran into several situations where we needed to lay out content either vertically or horizontally based on data available at run-time. In an effort to keep the conditional processing to a minimum and accomplish this goal, Chafic and I came up with a technique where we store the current position as properties of an object, and based on orientation set two variables, changeTarget and changeSource, to determine how to change the position at each iteration without having to check the orientation inside the loop.

Since the contitional is outside the loop, this improves performance, reduces the amount of duplicated code, and improves reusability.

Here’s an example of this implemenation that lays out a set of colored boxes both horizontally and vertically using the same layout code with only one conditional.

var data:Array = [0xFF0000, 0x00FF00, 0x0000FF];
var contentDepth:Number = 1;

function layoutContent(x:Number, y:Number, direction:String):Void {
var pos:Object = new Object();
pos.x = x;
pos.y = y;

var changeTarget:String;
var changeSource:String;

if (direction.substr(0, 1).toLowerCase() == "h") {
changeTarget = "x";
changeSource = "_width";
} else {
changeTarget = "y";
changeSource = "_height";
}

var max:Number = data.length;
var contentClip:MovieClip;

for (var i:Number = 0; i

REMOTE_ADDR and REMOTE_HOST not safe for use in security

There was some discussion today on CF-Talk about using CGI variables to secure an application and some confusion as to which CGI variables can be spoofed and if some are safe. Particularly there’s interest in blocking out specific IP addresses from accessing a web-application.

After some testing, I confirmed that even REMOTE_ADDR, the client’s IP address, and REMOTE_HOST, the client’s host name, can be spoofed very easily. ColdFusion can do this with the CFHTTP and CFHTTPPARAM tags and I’m sure other tools are available.

These spoofs worked with JRun’s built-in web server and through IIS. I’ve also spoofed REMOTE_HOST previously with an iPlanet installation to demonstrate poor security in a client’s application.

So if you’re thinking about using CGI variables to secure a site, you need to think again. If you need to secure by IP address, then do it at the router and not in application code.

Search and read CFDJ archives for free

I just stumbled upon this search engine I wasn’t aware of previously. LookSmart.com allows you to search the contents of magazine articles and displays the articles within the LooKSmart site itself. ColdFusion Developer’s Journal is one of the available magazines.

You can search CFDJ archives and come up with interesting things like all my articles (includes articles where I’m mentioned). The same search on the CFDJ web-site turned up nothing, so LookSmart seems like a winner.

How to make auto-complete work in custom components in Flash MX 2004

I just finished the custom actiosn portion of our BLDoc project and ran across Gregg Wygonik’s blog entry asking about code hints for custom components.

When you create your custom actions file as long as you use the form id="[com.blinex.charts.AreaChart]" for your classes then you’ll get code hints on strongly typed variables. The id must be the fully qualified class name and must be enclosed inside square brackets. This provide code hints both for variables declared using the fully qualified name and when the class is imported.

To get the code-hinting on the colon, the list of classes, you need to add a new folder to you custom actions that lists types. Here’s an example from our B-Line Charting Components 3.0, which will be released any day now.

<folder
   name="Types"
   id="Types"
   index="true"
   tiptext="Types that can be used for strong typing"
   helpid="0">

   <string
      name="AreaChart"
      tiptext="AreaChart type"
      text="AreaChart"
      helpurl="Help/BLineCharting30/content_72c6061a.htm" />

   <string
      name="BoxChart"
      tiptext="BoxChart type"
      text="BoxChart"
      helpurl="Help/BLineCharting30/content_23f3e2f8.htm" />

   <string
      name="BubbleChart"
      tiptext="BubbleChart type"
      text="BubbleChart"
      helpurl="Help/BLineCharting30/content_8497b033.htm" />
   .
   .
   .
</folder>

There is a big catch though, the suffix style code hints don’t support id’s that have a period in them. If you’re going to set up suffixes you have to use an id such as id="comblinexchartsAreaChart" which of course breaks the typed hints.

So, component developers have to choose–do they want to support typed hints or suffixed hints?