Wednesday, January 13, 2010

Transformation and Validation of XML

Some common Xml operation in .Net might be transforming,Validating or writing a XML file to a specific folder location. This can be done easily as explained below step by step.

How to Validate a Xml:

private bool _ValidationResult = true;
private string _ErrorMsg = string.Empty;

///
/// Method to validate XML using XSD
///

/// Source XmlReader object
/// XSD as string
/// Error
/// 'true' if validation succeeds, 'false' if validation fails
public ValidateXmlReturnType ValidateXml(XmlReader xmlReader, string xsdString)
{
_ValidationResult = true;
_ErrorMsg = string.Empty;
string validationErrorMsg = string.Empty;

// Set the validation settings.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

//Add the XML schema to an XmlSchemaSet and add to XmlReaderSettings.
XmlSchemaSet schemas = new XmlSchemaSet();

try
{
using (XmlReader schemaReader = XmlReader.Create(new StringReader(xsdString)))
{
schemas.Add("", schemaReader);
}
settings.Schemas.Add(schemas);
using (XmlReader newXmlReader = XmlReader.Create(xmlReader, settings))
{
while (newXmlReader.Read())
{
if (!string.IsNullOrEmpty(_ErrorMsg))
break;
}
}
}
catch (System.Xml.XmlException xmlException)
{
OnValidationFailed(xmlException.Message);
}

return new ValidateXmlReturnType(_ValidationResult, _ErrorMsg);

}

//Event handler to execute the validation and return the result.
void ValidationCallBack(object sender, ValidationEventArgs e)
{
OnValidationFailed(e.Message);

}
private void OnValidationFailed(string exceptionMessage)
{
if (_ValidationResult != false)
{
_ValidationResult = false;
}
if (!string.IsNullOrEmpty(_ErrorMsg) && !string.IsNullOrEmpty(exceptionMessage))
{
_ErrorMsg += System.Environment.NewLine;
}
_ErrorMsg += exceptionMessage;
}







How to Transform a Xml:

TrandformXMLReturnType Entity class definition

public class TransformXmlReturnType
{
bool _IsTransformed;
Stream _OutputXmlStream;

public TransformXmlReturnType(bool isTransformed, Stream outputXmlStream)
{
this._IsTransformed = isTransformed;
this._OutputXmlStream = outputXmlStream;
}
public bool IsTransformed
{
get
{
return _IsTransformed;
}
}

public Stream OutputXmlStream
{
get
{
return _OutputXmlStream;
}
}

}


Method to Do call transformation:

TransformXmlReturnType transformationResult = null;

using (XmlReader xmlReader = XmlReader.Create(this.SourceDataFilePath.ToString()))
{
this.WriteInformation("Attempting to transform source XML using XSLT");

try
{
transformationResult = TmEaiXmlProcessor.TransformXml(xmlReader, Xslt);
}
catch (System.Xml.Xsl.XsltException xsltException)
{
this.LogFatalException(xsltException, "Failed to transform XML", methodName);

}
catch (System.ArgumentNullException argumentNullException)
{
this.LogFatalException(argumentNullException, "Failed to transform XML: " +
argumentNullException.ParamName + " is null", methodName);
}
catch (Exception exp)
{
this.LogFatalException(exp, "Failed to transform XML", methodName);
}
}

if (transformationResult != null &&
transformationResult.IsTransformed && transformationResult.OutputXmlStream != null)
{
this.WriteInformation("Transformed XML successfully");
}
TranformXML Method:
///
/// Method to transform Source XML to Target XML using
/// XSL transformation
///

/// Source XmlReader object
/// XSLT as string
/// Transformed target XML XDocument object
public static TransformXmlReturnType TransformXml(XmlReader xmlReader, string xsltString)
{
bool isTransformed = true;

Stream outputXmlStream = new MemoryStream();
XslCompiledTransform xslt = new XslCompiledTransform();

try
{
// Load the style sheet.
xslt.Load(XmlReader.Create(new StringReader(xsltString)));
XPathDocument doc = new XPathDocument(xmlReader);
//Transform using IXPathNavigable input
xslt.Transform(doc, null, outputXmlStream);

}
catch (Exception exp)
{
isTransformed = false;
outputXmlStream = null;
throw exp;
}

outputXmlStream.Flush();
outputXmlStream.Seek(0, SeekOrigin.Begin);

return new TransformXmlReturnType(isTransformed, outputXmlStream);
}




How to Write a Xml to a destination path:

Input will xml Data and the destionation file path for writing a xml file in a specific location.
///
/// Writes XML data to destination file.
///

/// input XML data
/// destination File path
public static void WriteXmlToFile(XmlReader inputXmlReader, string destinationFilePath)
{
bool isEmptyElement = false;
using (FileStream fs = new FileStream(destinationFilePath, FileMode.Create))
{

XmlWriterSettings ws = new XmlWriterSettings();
ws.Indent = true;
using (XmlWriter writer = XmlWriter.Create(fs, ws))
{
// Parse the file and write each of the nodes.
while (inputXmlReader.Read())
{
switch (inputXmlReader.NodeType)
{
case XmlNodeType.Element:
writer.WriteStartElement(inputXmlReader.Name);
isEmptyElement = inputXmlReader.IsEmptyElement;

while (inputXmlReader.MoveToNextAttribute()) // Read attributes.
writer.WriteAttributes(inputXmlReader, false);

if (isEmptyElement)
{
writer.WriteFullEndElement();
isEmptyElement = false;
}

break;
case XmlNodeType.Text:
writer.WriteString(inputXmlReader.Value);
break;
case XmlNodeType.XmlDeclaration:
case XmlNodeType.ProcessingInstruction:
writer.WriteProcessingInstruction(inputXmlReader.Name, inputXmlReader.Value);
break;
case XmlNodeType.Comment:
writer.WriteComment(inputXmlReader.Value);
break;
case XmlNodeType.EndElement:
writer.WriteFullEndElement();
break;
}
}

}
}
}