A few years ago now, I was a (junior) member of the OASIS Entity Resolution TC, which produced the OASIS XML Catalogs specification (HTML, PDF). XML Catalogs are used to specify simple rules for re-writing or re-directing URIs in XML documents. This work was based on the catalogues used for SGML (from which XML is derived), so there was a lot of genuine long-term user experience factored into the design.
The most common use case for XML Catalogs is re-directing an HTTP URL for an XML Schema or DTD reference to a local copy of the file on your own file system. This aids both performance (HTTP is comparatively slow, and the remote HTTP server is usually that much slower again) and security (you don't have to trust that URLs in an incoming XML document are pointed at the correct schema, or the correct version of the schema). It also means that your different users or different systems can have their own catalogue file that controls where they get their schemas from, and there is no need to try and force one single configuration (a setup of HTTP URLs or a set of file locations) to work for all situations.
XML Catalogs is implemented now by a variety of software tools, e.g. Java, oXygen and XML Spy. However, I needed an implementation to use for a .NET application, and couldn't find a suitable implementation, so I have written one, called “xmlcatalog.net”. You can download it from
(or alternatively from http://xmlcatalog.net, once the domain re-direction kicks in properly).
As an example, suppose I have the following (trivial) XML document:
<?xml version="1.0" encoding="UTF-8"?> <schemaTest xmlns="http://www.example.com/schema/test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/schema/test schematest.xsd"> <a><c/></a> <b><d/></b> </schemaTest>
Note that the “xmi:schemaLocation” attribute indicates that the relative path to the Schema is “schematest.xsd”. This is a common situation that people end up in; not being able to specify a relative or absolute Schema URL that works for all users, they just assume that the Schema is in the same directory as the XML file (i.e. simplest possible relative path), and let end users sort out the problem for themselves.
Alternatively, you can use the following XML Catalog file:
<?xml version="1.0" encoding="UTF-8"?> <catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> <systemSuffix systemIdSuffix="schematest.xsd" uri="../xsd/schematest.xsd"/> </catalog>
which contains one rule: if you see a system ID (i.e. a physical schema location) which ends in “schematest.xsd”, then use the file whose path is “../xsd/schematest.xsd”, relative to the catalogue file. So, this one short XML file gives your users the ability to have their schemas in any location that best suits them – if the XML applications that they use are “ catalogue aware”, all they have to do is keep their catalogue file up-to-date.
In the .NET/Mono XML API, absolute and relative URLs that need to be used by parsers and such (e.g. schema locations) are passed to an XmlResolver. The standard version only provides the ability to convert relative URLs to absolute URLs. xmlcatalog.net provides a derived “ XmlCatalogResolver” class that uses your XML Catalog file(s) to re-write or re-direct the URIs that are being resolved. You can re-direct URIs to local files (using “file:///” URIs or relative paths that are relative to the catalogue file), or to alternative URLs. It is straightforward to configure a .NET/Mono XML parser to use XmlCatalogResolver:
using System.Xml; using System.Xml.Schema; ... XmlReaderSettings settings = new XmlReaderSettings();
// These two statements are important for W3C XML Schema validation. settings.ValidationType = ValidationType.Schema; settings.ValidationFlags = XmlSchemaValidationFlags.ProcessSchemaLocation | XmlSchemaValidationFlags.ReportValidationWarnings | XmlSchemaValidationFlags.AllowXmlAttributes | XmlSchemaValidationFlags.ProcessIdentityConstraints;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationHandler); settings.XmlResolver = new XmlCatalogResolver(catalogPath);
XmlReader reader = XmlReader.Create(xmlPath,settings);
// Read (parse) and validate the file. while (reader.Read());
By the way, my intention is that xmlcatalog.net should support both .NET and Mono, but I'm having some trouble getting NUnit to run under openSUSE 10.3, so I don't have my test suite running. It may already work under Mono (if you try it, let me know); when I get it tested against Mono, I will post an update.
At the download site
you can register to get access to our JIRA issue tracking system, if you need to search the existing issues or log new issues (bugs, feature requests, etc.). We are already using xmlcatalog.net as part of a customer project, and it's working well. If you use .NET or Mono for your XML, give it a try and let me know what you think.