Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
Dr.Bob's Delphi Notes Dr.Bob's Delphi Clinics Dr.Bob's Delphi Courseware Manuals
 Dr.Bob Examines... #76
See Also: other Dr.Bob Examines columns or Delphi articles

This article was first published in the UK Developers Group Magazine.

XML Documents, Schemas and Validation
How to produce an XML Schema (and do validation) when all you have is the XML Document

In this article, I'll show you how you can generate the XML schema from an XML document with only a few lines of code in Delphi (also applicable to Kylix or C++Builder).

Delphi 6 and 7 Enterprise include the XML Mapping Tool, which can map XML documents to datasets, but is also used by me (from time to time) to produce the XML Schema for a given XML document. Since the process of loading an XML document into the XML Mapper and producing the XML schema was fun at first, but a bit time consuming if you have lots of XML documents (not to mention boring), I was looking for another way to produce XML schemas for XML documents that do not have an XML schema produced already. In my search for a helpful technique, I noticed the XMLDataToSchema unit (in the Source\Xml directory) contains the TXMLDataImporter and registers it as an XML Schema Translator Factory. Even more interesting is the XMLSchema unit itself, which defines the IXMLSchemaDoc interface, as well as a number of schema helper functions such as GetXmlSchema, LoadXmlSchema, and LoadXmlSchemaStr. GetXmlSchema works on an IDOMDocument interface argument, in case you already have an opened XML document (component). LoadXmlSchema is able to load an XML document from filename, so is easier to use if you do not already have an open XML document (component) available. The LoadXmlSchemaStr function doesn't get the filename as argument, but rather the entire XML document itself as long string argument (this can be useful when you receive a dynamic XML document via a socket or memory stream for example).
In my case, all I needed was the LoadXmlSchema function, pass it a filename, and then work on the loaded XML schema/ For example saving it to disk again (using the same filename, but this time with the .xsd extension). LoadXmlSchema returns an IXMLSchemaDoc interface, and I only need to call the SaveToFile method in order to save the XML schema to disk.
The source code of a small console application that produces an .XSD XML schema based on an XML document is shown below:

  program XML2XSD;
    SysUtils, ActiveX,
    XMLDataToSchema, XMLSchema;
    XML,XSD: String;
    XMLSchemaDoc: IXMLSchemaDoc;
    if ParamCount = 0 then
      writeln('Usage: XML2XSD XML [XSD]')
    else // convert
      XML := ParamStr(1);
      XSD := ParamStr(2);
      if XSD = '' then
        XSD := ChangeFileExt(XML,'.xsd');
      XMLSchemaDoc := LoadXmlSchema(XML);
      XMLSchemaDoc := nil

The resulting console / command-line application is used on a frequent basis by me, generating XML schemas when I need them for the collection of XML documents that I have to work with.

Another piece of code that I sometimes use if a way to validate an XML model against its schema. This can be done with the validateOnParse property of the MSXML.DOMDocument, as follows:

    XML, XSDL: Variant;
    XSDL := CreateOLEObject('MSXML2.XMLSchemaCache.4.0');
    XSDL.validateOnLoad := True;
    XSDL.add('','MySchema.xsd'); // 1st argument is target namespace
    ShowMessage('Schema Loaded');
    XML := CreateOLEObject('MSXML2.DOMDocument.4.0');
    XML.validateOnParse := True;
    XML.resolveExternals := True;
    XML.schemas := XSDL;
These two little code snippets may help you when working with XML documents in Delphi for Win32.

For more recent information on this topic, check out my Delphi 2010 XML, SOAP & Web Services courseware manual.

This webpage © 2006-2010 by Bob Swart (aka Dr.Bob - All Rights Reserved.