Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to Create an XSD & XSLT Processor in C#

0.00/5 (No votes)
21 Oct 2016 1  
A good demo to know how you can implement an XSD & XSLT processor using C#

Introduction

The XSD (XML Schema Definition ) is useful to validate the Structure And Data type of your XML file, is often used to verify the non alteration of your input XML file before starting a process.

The XSLT (Extensible StyleSheet Language) allows you to transform XML file to another format, for example: XML to XML, or XML to HTML, etc.

To know more about the above processors, I recommend you visit the following links:

Background

This article may be useful for intermediate developers who have some basics in programming with C#, and XML.

Using the Code

A) Operating Process

The main idea of the application is:

  • Read a local XML file (using XmlReader class)
  • Specify an XSD file to use in the validation of XML schema through XmlReaderSettings class
  • If the XSD processor went well, then XSLT processor (using XslCompiledTransform class) will transform the current XML file to another one (XML file).

The following schema will explain it better:

Image 1

As inputs for our application, we will have:

1) XML File (named oldFile.xml)

XML
<?xml version="1.0" encoding="iso-8859-1"?>
<Application name="appXSD_XSLT">
  <TopObject name="topObject">
    <Actions>
      <Synchronization nDate="20120909">
        <Events>
			<Event index="0" action="insert" 
			name="product1" location="paris"/>
			<Event index="1" action="delete" 
			name="product2" location="lille"/>
		</Events>
      </Synchronization>
    </Actions>
  </TopObject>
</Application>

2) XSD File (named schema.xsd)

XML
<?xml version="1.0" encoding="iso-8859-1"?>
<xs:schema  
    elementFormDefault="qualified"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Application">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="TopObject">
          <xs:complexType>
            <xs:sequence>
				  <xs:element name="Actions">
						<xs:complexType>
						  <xs:sequence>
							<xs:element name="Synchronization">
							  <xs:complexType>
								<xs:sequence>
								  <xs:element name="Events">
									<xs:complexType>
									  <xs:sequence>
										<xs:element name="Event" 
										maxOccurs="unbounded">
										  <xs:complexType>
											<xs:attribute name="action" 
											type="xs:string" use="required" />
											<xs:attribute name="index" 
											type="xs:integer" use="required"/>
											<xs:attribute name="name" 
											type="xs:string"/>
											<xs:attribute name="location" 
											type="xs:string"/>
										  </xs:complexType>
										</xs:element>
									  </xs:sequence>
									</xs:complexType>
								  </xs:element>
								</xs:sequence>
								<xs:attribute name="nDate" 
								type="xs:string"/>
							  </xs:complexType>
							</xs:element>
						  </xs:sequence>
						</xs:complexType>
				  </xs:element>
			</xs:sequence>
			<xs:attribute name="name" type="xs:string" />
           </xs:complexType>
        </xs:element>
      </xs:sequence>
	 <xs:attribute name="name" type="xs:string" />
      </xs:complexType>
  </xs:element>
</xs:schema>

3) XSLT File (named transformation.xslt)

XML
 <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
 exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template 
  match="/Application/TopObject/Actions/Synchronization/Events">
    <Application>
	    <Actions>
			<xsl:apply-templates select="Event"></xsl:apply-templates>
		</Actions>
    </Application>
  </xsl:template>
  <xsl:variable name="lowerCase" 
  select="'abcdefghijklmnopqrstuvwxyz'"/>
  <xsl:variable name="upperCase" 
  select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
  <xsl:template match="Event">
   <Product action="{@action}" id="{@index}">
		  <givenName value="{concat(
							translate(substring(@name, 1, 1), $lowerCase, $upperCase), 
							translate(substring(@name,2), $upperCase, $lowerCase))
							}">
		  </givenName>
		  <location value="{concat(
							 translate(substring(@location, 1, 1), $lowerCase, $upperCase), 
							 translate(substring(@location,2), $upperCase, $lowerCase))
							}">
	     </location>
     </Product>
  </xsl:template>
</xsl:stylesheet>

B) Source Code

C# Code

C#
#region XSD Validation
       static bool _isValid = true;
       /// <summary>
       /// Validation du schéma XML
       /// </summary>
       public static void RunXsdValidation()
       {
           var fileInUse = "XSD";
           try
           {
               Console.WriteLine(String.Format("Starting XSD process."));
               var xmlSettings = new XmlReaderSettings();
               xmlSettings.Schemas.Add("", "../../Content/schema.xsd");
               xmlSettings.ValidationType = ValidationType.Schema;
               xmlSettings.ValidationEventHandler += TestValidationEventHandler;
               fileInUse = "XML";
               var xmlFile = XmlReader.Create("../../Content/oldFile.xml", xmlSettings);
               while (xmlFile.Read()) { }

               if (_isValid)
               {
                   Console.WriteLine(String.Format("XML Schema is valid."));
               }
               else
               {
                   Console.WriteLine("Error occurs on XML validation.
                   XML schema not valid.");
                   Environment.Exit(1);
               }
           }
           catch (FileNotFoundException ex)
           {
               if (fileInUse.Equals("XSD"))
               {
                    Console.WriteLine("XSD file not found \nError: '" +
                                      ex.Message + "'");
                    Environment.Exit((int)ExitCode.Error);
               }
               else if (fileInUse.Equals("XML"))
               {
                   Console.WriteLine("XML file not found.\nError : '" +
                                     ex.Message + "'");
                    Environment.Exit((int)ExitCode.Error);
               }
           }
           catch (Exception ex)
           {
               Console.WriteLine("Error occurs on XML validation.
                                  XML schema not valid. \nError: " + ex.Message);
               Environment.Exit(1);
           }
       }
       public static void TestValidationEventHandler(object sender, ValidationEventArgs args)
       {
           _isValid = false;
       }
       #endregion

       #region XSLT Transformation
       /// <summary>
       /// Transformer le fichier XML à partir d'un fichier XSLT
       /// </summary>
       public static void RunXslt()
       {
           var fileInUse = "XSLT";
           try
           {
               Console.WriteLine(String.Format("starting XSLT process"));
               // Load the style sheet.
               var xslt = new XslCompiledTransform();
               xslt.Load("../../Content/transformation.xslt");
               // Execute the transform and output the results to a file.
               fileInUse = "XML";
               xslt.Transform
               ("../../Content/oldFile.xml", "../../Content/newFile.xml");
               Console.WriteLine(String.Format("Fail occurs on transformation."));
           }
           catch (FileNotFoundException ex)
           {
               if (fileInUse.Equals("XSLT"))
               {
                   Console.WriteLine("XSLT file not found.");
                   Environment.Exit(1);
                }
               else if (fileInUse.Equals("XML"))
               {
                   Console.WriteLine("XML file not found.");
                   Environment.Exit((int)ExitCode.Error);
               }
           }
           catch (Exception ex)
           {
               Console.WriteLine
               ("Fail occurs on transformation. \nError : " + ex.Message);
               Environment.Exit((int)ExitCode.Error);
           }
       }
       #endregion
        private enum ExitCode : int
       {
            Success = 0,
            Error   = 1,
        }
       static void Main(string[] args)
       {
           //use XML Schema to validate.
           RunXsdValidation();
           //Transformation.
           RunXslt();
           Environment.Exit((int)ExitCode.Success);
       }

C) Result

After running the application, the output will be:

newFile.xml: Created on the Content Folder that is present in the racine folder of the application.

XML
<?xml version="1.0" encoding="utf-8"?>
<Application>
	<Actions>
		<Product action="insert" id="0">
			<givenName value="Product1" />
			<location value="Paris" />
		</Product>
		<Product action="delete" id="1">
			<givenName value="Product2" />
			<location value="Lille" />
		</Product>
	</Actions>
</Application>

In Closing

I hope that you appreciated this post. Try to download the source code. Please post your questions and comments below.

History

  • v1 21/10/2016: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here