65.9K
CodeProject is changing. Read more.
Home

How to Create an XSD & XSLT Processor in C#

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (10 votes)

Oct 21, 2016

CPOL

1 min read

viewsIcon

22225

downloadIcon

450

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:

As inputs for our application, we will have:

1) XML File (named oldFile.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 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 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

 #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 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