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)
="1.0"="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)
="1.0"="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)
="1.0"="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;
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
public static void RunXslt()
{
var fileInUse = "XSLT";
try
{
Console.WriteLine(String.Format("starting XSLT process"));
var xslt = new XslCompiledTransform();
xslt.Load("../../Content/transformation.xslt");
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)
{
RunXsdValidation();
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.
="1.0"="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