Spot the web RSS 2.0
# Monday, December 29, 2008

XML documents can reference optional documents that specify how the XML documents should be structured. These optional documents called Documents Type Definitions (DTDs) and Schemas.

There are two kinds of definition for schemas currently:

1. Microsoft XML Schema
It uses the extension .xdr (XML-Data Reduced) you can check the attached files for the this Schema syntax, it is an xml document, but has special elements and attributes.
2. W3C XML Schema
It uses the extension .xsd (XML Schema Definitions) also it is an XML Document with special elements.

The second approach, XSD Schema, has been supported by Microsoft .NET Framework and is the best approach for .NET developers.  Schema files are a special kind of XML file that define the structure of an XML file via some pre-defined elements and attributes.

Using this Schema file you can validate your XML file to make sure it fits to your application's needs and validate the inputs in order to prevent any exception in your code. 

The .Net framework gives you all the tools you need so that you can build XSD schemas and also validate them.

First, let's see how can we create a schema using XSD.exe file (It comes with Visual Studio):

The XML Schema Definition tool generates XML schema or common language runtime classes from XDR, XML, and XSD files, or from classes in a runtime assembly.

The following command generates an XML schema from myFile.xml and saves it to the specified directory

xsd myFile.xml /outputdir:myOutputDir

Consider that we have the following xml data file EmployeeList.xml:

<EmployeeList>
<Company ID="1">
<Employee>Employee11Employee>
<Employee>Employee12Employee>
<Employee>Employee13Employee>
Company>
<Company ID="2">
<Employee>Employee21Employee>
<Employee>Employee22Employee>
<Employee>Employee23Employee>
Company>
<Company ID="3">
<Employee>Employee31Employee>
<Employee>Employee32Employee>
<Employee>Employee33Employee>
<Employee>Employee34Employee>
Company>
EmployeeList>

Now, execute XSD.exe on the xml data file:

> XSD EmployeeList.xml

The result xsd file EmployeeList.xsd will be :

xml version="1.0" encoding="utf-8"?>
<xs:schema id="EmployeeList" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="EmployeeList" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Company">
<xs:complexType>
<xs:sequence>
<xs:element name="Employee" nillable="true" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent msdata:ColumnName="Employee_Text" msdata:Ordinal="0">
<xs:extension base="xs:string">
xs:extension>
xs:simpleContent>
xs:complexType>
xs:element>
xs:sequence>
<xs:attribute name="ID" type="xs:string" />
xs:complexType>
xs:element>
xs:choice>
xs:complexType>
xs:element>
xs:schema>

Second, now that we have our Schema let's see the steps that we need to do in order to validate against our schema (.NET 2.0):

1.      Read the XML file content as Stream, TextReader or XmlReader.

2.      Read the Schema file content as Stream, TextReader or XmlReader.

3.      Create a new instance of XmlSchema object.

4.      Set XmlSchema object by calling XmlSchema.Read() method and passing the content of Schema file
     and ValidationEventHandler method address to it.

5.      Create a new instance of XmlReaderSettings object.

6.      Set ValidationType for XmlReaderSettings object to Schema.

7.      Add your XmlSchema object to XmlReaderSettings Schemas collection by calling its Schemas.Add() method.

8.      Add your ValidationEventHandler method address to XmlValidationReader's ValidationEventHandler handler.

9.      Create a new instance of XmlReader object and pass your XML file content (as Stream or a Reader object)
     and XmlReaderSettings object to it.

10.  Call Read() method of the Reader or Stream object to contain your XML file content in a loop to parse
     and validate it completely.

11.  Add your logic to ValidationEventHandler method you created to implement what you want to be done in
     the validation process.


Here is the code to accomplish this:

private void ValidatingProcess(string XSDPath, string XMLPath)
{
    try
    {
        // 1- Read XML file content
        this.Reader = new XmlTextReader(XMLPath);
 
        // 2- Read Schema file content
        StreamReader SR = new StreamReader(XSDPath);
 
        // 3- Create a new instance of XmlSchema object
        XmlSchema Schema = new XmlSchema();
        // 4- Set Schema object by calling XmlSchema.Read() method
        Schema = XmlSchema.Read(SR, 
            new ValidationEventHandler(ReaderSettings_ValidationEventHandler)); 
 
        // 5- Create a new instance of XmlReaderSettings object
        XmlReaderSettings ReaderSettings = new XmlReaderSettings();    
        // 6- Set ValidationType for XmlReaderSettings object
        ReaderSettings.ValidationType = ValidationType.Schema;                
        // 7- Add Schema to XmlReaderSettings Schemas collection
        ReaderSettings.Schemas.Add(Schema); 
 
        // 8- Add your ValidationEventHandler address to
        // XmlReaderSettings ValidationEventHandler
        ReaderSettings.ValidationEventHandler +=
            new ValidationEventHandler(ReaderSettings_ValidationEventHandler);
 
        // 9- Create a new instance of XmlReader object
        XmlReader objXmlReader = XmlReader.Create(Reader, ReaderSettings);
 
 
        // 10- Read XML content in a loop
        while (objXmlReader.Read())
        { /*Empty loop*/
 
    }//try
    // Handle exceptions if you want
    catch (UnauthorizedAccessException AccessEx)
    {
        throw AccessEx;
    }//catch
    catch (Exception Ex)
    {
        throw Ex;
    }//catch
}
 
private void ReaderSettings_ValidationEventHandler(object sender, 
    ValidationEventArgs args)
{
    // 11- Implement your logic for each validation iteration
    string strTemp;
    strTemp = "Line: " + this.Reader.LineNumber + " - Position: " 
        + this.Reader.LinePosition + " - " + args.Message; 
 
    this.Results.Add(strTemp);
}

Monday, December 29, 2008 1:30:46 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [1] - Trackback
.Net | C# | Serialization | Visual Studio | XML | XSD
# Wednesday, December 24, 2008

Don't use your web methods to return strings as most programmers do, use them to return true XMLs.


instead of using this:

[WebMethod]
public string MyLameWebMethod()
{
XmlDocument dom = new XmlDocument();
// load XML Data ...
return dom.OuterXml;
}

Now when we want to read it on the client side we want the XML and then the operation is:
XML -> String -> XML


Use this:

[WebMethod]
public XmlDocument MyBetterWebMethod()
{
XmlDocument dom = new XmlDocument();
// load some XML ...
return dom;
}

Here we are skipping over the String step and using much more valid XML document.


Now you are avoiding an added level of transferring your XML document to string and then back to XML.
Wednesday, December 24, 2008 12:01:38 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | C# | XML
# Monday, March 10, 2008

This article discusses the delegate type and how it can be used to point to methods in the application which can be invoked at later time. This article demonstrates also the delegate ability to multicast and delegate covariance.

A delegate is a type-safe object that can point to another method (or possibly multiple methods) in the application, which can be invoked at later time.

Delegates also can invoke methods Asynchronously.

A delegate type maintains three important pices of information :

  1. The name of the method on which it make calls.
  2. Any argument (if any) of this method.
  3. The return value (if any) of this method.

Defining a Delegate in C#

when you want to create a delegate in C# you make use of delegate keyword.

The name of your delegate can be whatever you desire. However, you must define the delegate to match the signature of the method it will point to. fo example the following delegate can point to any method taking two integers and returning an integer.

public delegate int DelegateName(int x, int y);

A Delegate Usage Example

namespace MyFirstDelegate

{

    //This delegate can point to any method,

    //taking two integers and returning an

    //integer.

    public delegate int MyDelegate(int x, int y);

    //This class contains methods that MyDelegate will point to.

    public class MyClass

    {

        public static int Add(int x, int y)

        {

            return x + y;

        }

        public static int Multiply(int x, int y)

        {

            return x * y;

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            //Create an Instance of MyDelegate

            //that points to MyClass.Add().

            MyDelegate del1 = new MyDelegate(MyClass.Add);

            //Invoke Add() method using the delegate.

            int addResult = del1(5, 5);

            Console.WriteLine("5 + 5 = {0}\n", addResult);

            //Create an Instance of MyDelegate

            //that points to MyClass.Multiply().

            MyDelegate del2 = new MyDelegate(MyClass.Multiply);

            //Invoke Multiply() method using the delegate.

            int multiplyResult = del2(5, 5);

            Console.WriteLine("5 X 5 = {0}", multiplyResult);

            Console.ReadLine();

        }

    }
}

Delegate ability to Multicast

Delegate ability to multicast mean that a delegate object can maintain a list of methods to call, rather than a single method
if you want to add a method to the invocation list of a delegate object , you simply make use of the overloaded += operator, and if you want to remove a method from the invocation list you make use of the overloaded operator -= .

Note:Multicast delegate must contain only methods that return void, or you will get a run time exception.

A Multicast Delegate Example

namespace MyMulticastDelegate

{

    //this delegate will be used to call more than one

    //method at once

    public delegate void MulticastDelegate(int x, int y);

    //This class contains methods that MyDelegate will point to.

    public class MyClass

    {

        public static void Add(int x, int y)

        {

            Console.WriteLine("You are in Add() Method");

            Console.WriteLine("{0} + {1} = {2}\n", x, y, x + y);

        }

        public static void Multiply(int x, int y)

        {

            Console.WriteLine("You are in Multiply() Method");

            Console.WriteLine("{0} X {1} = {2}", x, y, x * y);

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            //Create an Instance of MulticastDelegate

            //that points to MyClass.Add().

            MulticastDelegate del = new MulticastDelegate(MyClass.Add);

            //using the same instance of MulticastDelegate

            //to call MyClass.Multibly() by adding it to it's

            //invocation list.

            del += new MulticastDelegate(MyClass.Multiply);

            //Invoke Add() and  Multiply() methods using the delegate.

            //Note that these methods must have a void return vlue

            Console.WriteLine("****calling Add() and Multibly() Methods.****\n\n");

            del(5, 5);

 

            //removing the Add() method from the invocation list

            del -= new MulticastDelegate(MyClass.Add);

            Console.WriteLine("\n\n****Add() Method removed.****\n\n");

            //this will invoke the Multibly() method only.

            del(5, 5);

        }

    }

}

Delegate Covariance

Assume you are designing a delegate that can point to methods returning a custom class type:

//Define a delegate pointing to methods returning Employee types.

public delegate Employee EmployeeDelegate();

if you were to derive a new class from Employee Type named SalesEmployee and wish to create a delegate type that can point to methods returning this class type you would be required to define an entirely new delegate to do so

//a new  delegate pointing to methods returning SalesEmployee types.

public delegate SalesEmployee SalesEmployeeDelegate();

Example

namespace MyEmployeesDelegate

{

    //Define a delegate pointing to methods returning Employee types.

    public delegate Employee EmployeeDelegate();

    //a new  delegate pointing to methods returning SalesEmployee types.

    public delegate SalesEmployee SalesEmployeeDelegate();

    class Program

    {

        public static Employee GetEmployee()

        {

            return new Employee();

        }

        public static SalesEmployee GetSalesEmployee()

        {

            return new SalesEmployee();

        }

        static void Main(string[] args)

        {

            EmployeeDelegate empDel = new EmployeeDelegate(GetEmployee);

            Employee emp = empDel();

            SalesEmployeeDelegate salesEmpDel = new SalesEmployeeDelegate(GetSalesEmployee);

            SalesEmployee emp2 = salesEmpDel();

        }

    }

    public class Employee

    {

        protected string firstName;

        protected string lastName;

        protected int Age;

        public Employee()

        { }

        public Employee(string fName, string lName, int age)

        {

            this.firstName = fName;

            this.lastName = lName;

            this.Age = age;

        }

 

    }

    public class SalesEmployee : Employee

    {

        protected int salesNumber;

        public SalesEmployee()

        { }

        public SalesEmployee(string fName, string lName, int age, int sNumber): base(fName, lName, age)

        {

            this.salesNumber = sNumber;

        }

    }

}

It would be ideal to build a single delegate type that can point to methods returning either Employee or SelesEmployee types.
Covariance allows you to build a single delegate that can point to methods returning class types related by classical inheritance.

Delegate Covariance Example

namespace DelegateCovariance

{

    //Define a single delegate that may return an Employee

    // or SalesEmployee

    public delegate Employee EmployeeDelegate();

    class Program

    {

        public static Employee GetEmployee()

        {

            return new Employee();

        }

        public static SalesEmployee GetSalesEmployee()

        {

            return new SalesEmployee();

        }

        static void Main(string[] args)

        {

            EmployeeDelegate emp = new EmployeeDelegate(GetEmployee);

            Employee emp1 = emp();

            EmployeeDelegate empB = new EmployeeDelegate(GetSalesEmployee);

            //to obtain a derived type you must perform an explicit cast.

            SalesEmployee emp2 = (SalesEmployee)empB();

        }

    }

    public class Employee

    {

        protected string firstName;

        protected string lastName;

        protected int Age;

        public Employee()

        { }

        public Employee(string fName, string lName, int age)

        {

            this.firstName = fName;

            this.lastName = lName;

            this.Age = age;

        }

    }

    public class SalesEmployee : Employee

    {

        protected int salesNumber;

        public SalesEmployee()

        { }

        public SalesEmployee(string fName, string lName, int age, int sNumber): base(fName, lName, age)

        {

            this.salesNumber = sNumber;

        }

    }

}

I hope you are now have a good idea with the creation and usage of delegates types.

Monday, March 10, 2008 10:28:46 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | AJAX | Microsoft | Programming | C#
Navigation
Archive
<July 2010>
SunMonTueWedThuFriSat
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Guy Levin
Sign In
Statistics
Total Posts: 63
This Year: 0
This Month: 0
This Week: 0
Comments: 14
Themes
All Content © 2010, Guy Levin