Login   Search   
XML-FX.COM
<September 2010>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789
SAIDValidator - South African ID Validator Webservice

SAIDValidator - South African ID Validator Webservice

SAIDValidator is an ASP.NET webservice to validate South African Person ID numbers. It provides validation of a person ID by calculating the check-digit (digit-13), and extracts the date-of-birth, gender, citizenship, sequence and other information.

The following sections provide further information:

Homepage SAIDValidator homepage.
Documentation Standard WSDL service description and web method documentation.
Schemas The XML-schemas for the different object types used as parameters and return values of the webservice methods.
Blog The original blog post for more information: How to validate SA Identity Numbers.
Test Page A standard input form that when submitted returns an analysis and validation of the ID number. It calls the SAIDValidator webservice.

 

 

XML-FX.COM xfxDoc Tool

XML-FX.COM xfxDoc Tool

The xfxDoc tool documents XML-schemas using the Altova XMLSpy XML-schema documentation format to produce Microsoft HTML Help documentation (.chm) files that feature auto-generated table-of-contents, index, and full-text search.

Links

Motivation

As the use of XML as the protocol for information interfaces is becoming more common and accepted in the industry, two important facts are emerging:

  • The W3C consortium XML-schema or XSD-standard is the major standard for describing the structure and syntax of XML data.
  • More than ever, these XML-schemas are becoming huge, complex and more resource-intensive, both in human- and computer- terms.

An important part of managing and utilizing large schema sets is to provide comprehensive and easy-to-use documentation describing the schemas. Altova XMLSpy provides a handy capability to do this, in both a Microsoft Word format and an HTML format. The advantage of the HTML documentation is that it can be easily published, as well as providing the following additional important advantages:

  • The documentation provides XML-schema structure description using diagrams. The diagram constructs used have become a de-facto industry standard in terms of schema documentation. The HTML page also provides hot-spots within the diagrams that provide easy navigation between schema documentation constructs.
  • The documentation text is easy to understand and is comprehensive.
  • 'Type', 'Used By' and 'Children' sections provide easy navigation around the documentation in terms of parent-child relationships.
  • Most importantly, the documentation is generated automatically, with very little user intervention.

However, when the schema(-sets) get moderately complex, the HTML documentation is inadequate, for the following reasons:

  • The documentation takes the form of a single page, or sets of related pages, the size of which can easily be in excess of a few megabytes. This results in a slower loading page in the browser, the page navigation performance of the loaded page is poor, and the user experience is substantially degraded. For very large schemas, the page is often unable to load and even causes the browser to throw an exception.
  • The documentation has a very simple indexing section at the top of the page, which is not efficient. It has no real table-of-contents, keyword index, or full-text search, which becomes more important as the size of the documentation increases.

How it works

The xfxDoc application takes as input the HTML page(s) generated by the XMLSpy XML-schema 'Generate Documentation' command, and outputs a fully-featured compiled HTML Help (.chm) file. Functionality includes:

  • Utilizing the XMLSPY documentation 'standard' completely;
  • Automatically executes XMLSPY via the XMLSPYLIB automation interface and generates documentation according to user-presets;
  • Splits the generated single HTML documentation page(s) into separate HTML pages, one page per main topic;
  • Builds an HTML Help table-of-contents (.hhc), and index (.hhk) file automatically from the schema construct type and construct name that it derives from the contents of each page;
  • Rebuilds the HTML image hot-spot and text hyperlinks automatically to retain the original XMLSPY navigation capabilities;
  • Uses a user-specified HTML Help project template (with replaceable parameters), to automatically generate the target HTML Help project file (.hhp) which can directly compiled;
  • Automatically executes the Microsoft HTML Help Compiler (hhc.exe) to build the final .chm help file;
  • Allows further enhancement to the generated documentation via user-coded plug-in assemblies.

The resulting HTML Help file is fully-featured, easy to navigate, and provides great performance.

xfxDoc is provided as a .NET Windows Forms application.

 

 

Using XmlSerializer with external serializable types

Using XmlSerializer with external serializable types

Table of contents

Introduction

Often XML data interfacing or exchange structures are required to be adaptable to changing business and data needs. One solution to this is to provide an xs:anyType element to the data, with the idea that this data can be provided by another code class, assembly or even another application as part of the interface realization. The xs:anyType element is unconstrained and can contain any valid XML tags and content.

Simple extensible class

In Figure 1 below, a simple extensible XML data structure is defined with the extensible unconstrained element represented by the ExternData element in the diagram.

Simple extensible XML data structure

Figure 1 : A simple extensible XML data structure

If the XML schema represented in Figure 1 above (extdata.xsd in the 'schema' solution folder) is run through an X/O mapper that supports serialization using the .NET XmlSerializer class (such as Microsoft's XSD.EXE), the class member generated for the ExternData is of type System.Object as shown below:

  1. [System.Xml.Serialization.XmlElementAttribute("ExternData")]     
  2. public object ExternData     
  3. {     
  4.     get { return externData; }     
  5.     set { externData = value; }     
  6. }  

The complete C# source-code of the serialization class is shown below (Test_1 : ExtensibleDataType.cs):

External data class

Similarly, an XML schema can be defined for the data that is contained in the ExternData element tag. For this example the schema shown in Figure 2 below is used (website.xsd in the 'schema' solution folder):

An external XML data structure to be placed in the 'ExternData' element

Figure 2 : An external XML data structure to be placed in the 'ExternData' element

Combining XML data based on the schemas in Figures 1 and 2, a sample XML data file can be produced which will validate with the schema in Listing 1 (test.002.xml in the 'schema' solution folder):

The complete C# source-code of the external data serialization class is shown below (WebsiteData : WebsiteData.cs):

Test #1: Set an instance of the external data class

The Test_1 console application (Test_1.csproj) attempts to read the file test.001.xml which contains the same data as Listing 2 without the additional ExternData element. Since this element does not exist, it is not bound to the ExternData property of the ExtensibleDataType class in Listing 1, and the value of this property is null. The application then creates a WebsiteData.Website object and then sets the ExternData property to this object. The application Main() method source-code is shown below (Program.cs):

When the object is subsequently serialized, the XmlSerializer throws an exception with the following message:

"The type WebsiteData.Website was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."

This means that the XmlSerializer could not find the WebsiteData.Website type definition and therefore was unable to serialize the ExternData object. Although this was not unexpected, it is problematic since the original concept of allowing externally defined data to be injected into the base data is not working.

Two interesting points should be noted:

  1. If the Website class is moved into the same assembly as the ExtensibleDataType, the de-/serialization proceeds normally. However, this is still contrary to the whole extensibility concept.
  2. If the XML file test.002.xml (which contains a valid Website element) is read instead of test.001.xml, the XmlSerializer de-serializes it without error, but the ExternData now consists of two System.Xml.XmlNode objects which carry the data. Again, this is a problem, since a part of the data is now held in serialization classes (read: domain rich), while another part is held as an XML DOM, which is a model of the XML data structure and format, and not a model of the underlying domain data that serialization classes provide.

Test #2: Use a proxy serializer class

The following principle provides the solution to the problem of Test #1: a proxy object is required which can be triggered by the XmlSerializer at the correct time to de-serialize data stored in the ExternData element as an XML attribute. This must provide the type information to the XmlSerializer so that it can instantiate and bind the required external data object when de-serializing the XML data. Obviously the reverse process for serialization should also apply.

Listing 5 below provides the source-code for ExternDataSerializer which is an example of a proxy serialization class:

The following are points of interest in the implementation of the ExternDataSerializer class:

  1. In order for the class to be triggered by the XmlSerializer during de-/serialization, the IXmlSerializable interface must be implemented.
  2. In the WriteXml method, an attribute with the name 'Type' is written, and its value contains the AssemblyQualifiedName, which provides sufficient information for the XmlSerializer to correctly de-/serialize the external class, even if the class is defined in a different assembly.
  3. In the ReadXml method, the 'Type' attribute is read, the System.Type of the required external data class is determined, and the XmlSerializer can instantiate and de-serializer the object correctly.
  4. The proxy class retains a reference to the external data object created by the XmlSerializer. This is required, as the proxy class has to be implicitly cast from the external type during serialization, and to the external type during de-serialization. This functionality is provided by the two implicit cast methods.

So what else has to change in order to get this solution to work? Firstly, the external data type has to derive from a base class that is not of type System.Object. The reason for this is that the implicit cast operators cannot cast between the ExternDataSerializer class and System.Object. In Listing 3 the Website class now derives from a base class AppData.Interface.ExternData:

  1. public partial class Website : AppData.Interface.ExternData  
  2. {  
  3.   ..  
  4. }  

The AppData.Interface.ExternData class is shown below:

  1. namespace AppData.Interface  
  2. {  
  3.     public abstract class ExternData { }  
  4. }  

The AppData.Interface.ExternData class is abstract and empty. In a real application this class can provide other data which may be required as part of the data contract or interface.

The ExtensibleDataType class also has to change: first the externData member has to be of type AppData.Interface.ExternData:

  1. private AppData.Interface.ExternData externData;  

The serialization property ExternData also has to change:

  1. [System.Xml.Serialization.XmlElementAttribute("ExternData", Type = typeof(ExtData.ExternDataSerializer))]  
  2. public AppData.Interface.ExternData ExternData  
  3. {  
  4.     get { return externData; }  
  5.     set { externData = value; }  
  6. }  

Test_2 (test_2.csproj) provides the working console application implemented as above.

Dependencies and Packaging

Figure 3 below shows a class dependency diagram of the important classes:

Main classes and dependencies

Figure 3 : Main classes and dependencies

In a real application, it may be prudent to package the ExternDataSerializer and the ExternData class in the same assembly. The ExtensibleDataType is often generated automatically and repeatedly from an XML schema, and should be packaged by itself (or with other AppData types). The Website class (which represents all external data types) should be in its own assembly. Note that neither the Website or the ExtensibleDataType are directly dependent on each other. The only requirement to add other external data types to the system is to make the external data type a subclass of ExternData, and to provide a reference to the assembly containing the ExternData type.

Test #3: A parameterized proxy serializer class

Test_3 (test_3.csproj) provides a similar solution to Test_2 but using a parameterized (generic) proxy serializer class. The source code is shown in Listing 6 below:

The only other change required is the serialization property ExternData of the ExtensibleDataType class:

  1. [System.Xml.Serialization.XmlElementAttribute("ExternData", Type = typeof(ExtData.ExternDataSerializer <AppData.Interface.ExternData>))]  

Code safety

In Listing 4 line 24 and 25 the application has to check if the external data object it is working with is of the type it is expecting. Although this is annoying, it is required since the definition of the schema allows for an instance of any type to be present.

 

Rss