Validate XML with a XSD Schema without changing the XML using C# - c#

I have an XML file without a Schema in the XML, and I need to validate the XML against a XSD schema. I have seen many examples where you inject the XSD in to the XML and then validate the XML. I don't want to change the XML, is it possible to validate the XML, against the schema without change the XML?

It's easy to code with a few lines in C#.
I created a simple command line interface utility that takes two parameters: XML, XSD and does verification.
You can download it here.
Here's the main code:
// 1- Read XML file content
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*/}

You can add the schema to the xml doc
doc.Schemas.Add(schema);
And then validate it
bool xmlvalid = true;
string lastXmlError = "";
doc.Validate(new System.Xml.Schema.ValidationEventHandler(
delegate(object sender, System.Xml.Schema.ValidationEventArgs args)
{
if (args.Severity == System.Xml.Schema.XmlSeverityType.Error)
{
xmlvalid = false;
lastXmlError = args.Message;
}
}));
if (!xmlvalid)
//raise error

Provide a ValidationEventHandler only if you want to keep validating the document beyond the first validation error. Otherwise, just do this:
private bool ValidateDocument(string xmlFile, string xsdFile)
{
XmlReaderSettings settings = new XmlReaderSettings{ValidationType
= ValidationType.Schema};
settings.Schemas.Add(XmlSchema.Read(XmlReader.Create(xsdFile)));
XmlReader reader = XmlReader.Create(xmlFile, settings);
try
{
while(reader.Read());
return true;
}
catch (XmlException ex)
{
// XmlException indicates a validation error occurred.
return false;
}
}
The following links provide more information:
http://msdn.microsoft.com/en-us/library/1xe0740a.aspx
http://support.microsoft.com/kb/307379

Related

C# validate a xml vs. xsd using XmlReader; How to fix following error without changing the xsd

I am trying to validate a xml file againg a xsd, but for some reason the following Errorr occures.
Strange is that different programms, which do the same does not show an error.
How can i change the settings for the xsd to not check for missing attributes and just ignore them?
Code:
static void ValidateXml(string xmlFile, string xsdFile)
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(null, xsdFile);
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += ValidationEventHandler;
using (XmlReader reader = XmlReader.Create(xmlFile, settings)) // failing here
{
while(reader.Read())
{
// Reading and doing nothing with the xml file.
}
}
}
Error Message:
System.Xml.Schema.XmlSchemaValidationException: "The 'http://www.w3.org/XML/1998/namespace:lang' attribute is not declared."
I tried it using XMlDocument, but that doesnt work for me, cause i am reading of xml files up to 2 gb.

How to validate xml, not containing xmlns=..., with c# XmlSerializer?

I am working with Mismo 2.3.1, dtd based schema. I converted the dtd to xsd and then generated c# code to serialize/deserialze object representations of the xml doc.
Given a valid mismo 2.3.1 xml doc, I can deserialize into my generated C# class.
I have code working to use XmlSerializer along with XmlReaderSettings and XmlSchmeas collection, reading in my converted xsd.
If I put xmlns="http://mySchema..." in the root element, and try to validate intentionally invalid xml, works as expected, my validation event gets pinged with accurate description.
If I take out the xmlns attribute, then i get "could not find schema information for element [my root element]"
Any idea on how to validate xml that comes in without the xmlns spec? Any settings to say to the serializer "use this schema when you come across this element"?
Thanks in advance!
static void Main() {
var settings = new XmlReaderSettings();
settings.NameTable = new NameTable();
var nsMgr = new XmlNamespaceManager(settings.NameTable);
nsMgr.AddNamespace("", "http://example.com/2013/ns"); // <-- set default namespace
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add(null, #"C:\XSDSchema.xsd"); // <-- set schema location for the default namespace
var parserCtx = new XmlParserContext(settings.NameTable, nsMgr, XmlSpace.Default);
using (var reader = XmlReader.Create(#"C:\file.xml", settings, parserCtx)) {
var serializer = new XmlSerializer(typeof(Foo));
Foo f = (Foo)serializer.Deserialize(reader);
}
}

validate xml file using xsd in C#.. How much does it actually validate?

Have have been trying to make a validator for my xml files. I have used some of the other examples that can be found on this site (like How to validate an XML document?).
I just don't see it working the way I expect. What does actually get validated?
Almost no matter what I change in the xml file, the validator dosent sees it as an error. I thought the validator would see if the xml file contains an element not defined in the xsd. The validator only catches normal xml syntax errors.
So whats the point of using the xsd if it doesn't have an influence?
My validator
string xsd_file = "Message.xsd";
XmlSchema xsd = new XmlSchema();
xsd.SourceUri = xsd_file;
XmlSchemaSet ss = new XmlSchemaSet();
ss.ValidationEventHandler += new ValidationEventHandler(ValidationEventHandler);
ss.Add(null, xsd_file);
if (ss.Count > 0)
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add(ss);
settings.Schemas.Compile();
settings.ValidationEventHandler += new ValidationEventHandler(ValidationEventHandler);
XmlTextReader r = new XmlTextReader(filepath);
using (XmlReader reader = XmlReader.Create(r, settings))
{
try
{
while (reader.Read())
{
}
}
catch (XmlException ex)
{
throw;
}
}
}
The code for the validation eventhandler is missing.
Looking at my working code which is slightly different I have this
settings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema | XmlSchemaValidationFlags.ReportValidationFlags;
Can't remember why I had to add it though.
First thing to do is make sure the eventhandler is getting triggered, after that it may be a problem with your xsd.

C# de-serialise Xml to object and serialise back to Xml again

I would like to use JsonFx to convert XML to/from custom types and LINQ queries. Can anyone please provide an example to de-serialisation and serialisation back again?
Here's an example of the XML I'm working with.
XML pasted here: http://pastebin.com/wURiaJM2
JsonFx Supports several strategies of binding json to .net objects including dynamic objects. https://github.com/jsonfx/jsonfx
Kind regards
Si
PS I did try pasting the xml document into StackOverflow but it removed a lot of the documents quotes and XML declaration.
Here's a method that I have used. It may require some tweaking:
public static string SerializeObject<T>(T item, string rootName, Encoding encoding)
{
XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.OmitXmlDeclaration = true;
writerSettings.Indent = true;
writerSettings.NewLineHandling = NewLineHandling.Entitize;
writerSettings.IndentChars = " ";
writerSettings.Encoding = encoding;
StringWriter stringWriter = new StringWriter();
using (XmlWriter xml = XmlWriter.Create(stringWriter, writerSettings))
{
XmlAttributeOverrides aor = null;
if (rootName != null)
{
XmlAttributes att = new XmlAttributes();
att.XmlRoot = new XmlRootAttribute(rootName);
aor = new XmlAttributeOverrides();
aor.Add(typeof(T), att);
}
XmlSerializer xs = new XmlSerializer(typeof(T), aor);
XmlSerializerNamespaces xNs = new XmlSerializerNamespaces();
xNs.Add("", "");
xs.Serialize(xml, item, xNs);
}
return stringWriter.ToString();
}
And for Deserialization:
public static T DeserializeObject<T>(string xml)
{
using (StringReader rdr = new StringReader(xml))
{
return (T)new XmlSerializer(typeof(T)).Deserialize(rdr);
}
}
And call it like this:
string xmlString = Serialization.SerializeObject(instance, "Root", Encoding.UTF8);
ObjectType obj = Serialization.DeserializeObject<ObjectType>(xmlString);
Hope this helps. The rootName parameter in the Serialize method lets you customize the value of the root node in the resulting xml string. Also, your classes must be decorated with the proper Xml attributes which will control how an entity is serialized.
This post explains how to create an XSD and a Classes from an XML file and then covers serialisation and de-serialisation.
http://geekswithblogs.net/CWeeks/archive/2008/03/11/120465.aspx
Using this technique with the XSD.exe to create an XSD and then classes in a CS file I was able to serialisation and then de-serialisation back again.
However the serialisation process does not create an exact representation of the source XML, so there's still some post work to be done there.

Problem validating XML against DTD in C#

This has been bugging me for a couple days. I'm trying to load a XML from an uploaded file to into an XmlDocument object and get the following yellow-screen-of-death:
For security reasons DTD is prohibited in this XML document. To enable DTD processing set the ProhibitDtd property on XmlReaderSettings to false and pass the settings into XmlReader.Create method.
Here's my code. You can clearly see I'm setting ProhibitDtd to false.
public static XmlDocument LoadXml(FileUpload fu)
{
var settings = new XmlReaderSettings
{
ProhibitDtd = false,
ValidationType = ValidationType.DTD
};
var sDtdPath = string.Format(#"{0}", HttpContext.Current.Server.MapPath("/includes/dtds/2.3/archivearticle.dtd"));
settings.Schemas.Add(null, sDtdPath);
var r = XmlReader.Create(new StreamReader(fu.PostedFile.InputStream), settings);
var document = new XmlDocument();
document.Load(r);
return document;
}
Add XmlResolver=null to your XmlReaderSettings. This will prevent the xmlDocument from trying to access the DTD. If you need to validate, do that in a separate operation.

Categories