?
Solved

XML Validation against schema not working c#

Posted on 2008-02-08
9
Medium Priority
?
1,338 Views
Last Modified: 2012-08-14
I am validating a xml string against a predefined schema as shown in the code. But the reader is only checking for the wellformedness but not the elements.

For example. if I pass a string link

<root>Hello</root>

the method should reject the string. But the code says the input xml is valid where it is not.

Am I missing something in it. I feel I should add a namespace somewhere.

Thanks.
internal static bool IsValid(string xml)
       {
           errorsExist = false;
           try
           {
               XmlSchemaSet schemaSet = new XmlSchemaSet();
               schemaSet.Add(null, new XmlTextReader(new StringReader(_schema.Trim()))); // _schema consists of the schema definition
               XmlReaderSettings settings = new XmlReaderSettings();
               settings.ValidationType = ValidationType.Schema;
               settings.Schemas = schemaSet;
               settings.ValidationEventHandler += new ValidationEventHandler(LogErrors);
               XmlReader reader = XmlReader.Create(new XmlTextReader(new StringReader(xml.Trim())), settings);
               while (reader.Read()) ;
           }
           catch (Exception e)
           {
               errorsExist = true;
           }
           return (!errorsExist);
       }
 
       private static void LogErrors(object sender, ValidationEventArgs args)
       {
           errorsExist = true;
       }
 
Schema I am using 
 
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Schema"
    targetNamespace="http://Schema.xsd"
    elementFormDefault="qualified"
    xmlns="http://Schema.xsd"
    xmlns:mstns="http://Schema.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
	<xs:element name="Employee">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="Firstname" type="xs:string"></xs:element>
				<xs:element name="Lastname" type="xs:string"></xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
 
</xs:schema>

Open in new window

0
Comment
Question by:Vootan
  • 6
  • 3
9 Comments
 
LVL 13

Expert Comment

by:Velio
ID: 20860954
the following input will return false:

<root xmlns=\"http://Schema.xsd\">Hello</root>
0
 
LVL 13

Expert Comment

by:Velio
ID: 20860956
ignore the escaping backslashes :D
0
 

Author Comment

by:Vootan
ID: 20862658
But we cannot enforce the user to enter the namespace in the xml, right?
Is there a way to validate the xml without that namespace?
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
LVL 13

Expert Comment

by:Velio
ID: 20864573
unfortunately you have to reference the schema somewhere in the xml you're validating. one possible solution is to load the xml you're validating into a XmlDocument object, manually add the xmlns attribute to the DocumentElement and validate the xml document. I will try to give you a code sample.
0
 
LVL 13

Accepted Solution

by:
Velio earned 2000 total points
ID: 20864620
Something like this.

I think this is rather crude but will work fine for xml documents that aren't too big.

if you can optimise it to use XmlDocument.Validate without having to save the modified xml, you might want to do that. it didn't quite work when i tried.

hope it helps.
        internal static bool IsValid(string xml)
        {
            errorsExist = false;
            try
            {                
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(new StringReader(xml.Trim()));
                if (xmlDocument.DocumentElement.Attributes.GetNamedItem("xmlns") == null)
                {
                    XmlAttribute attribute = xmlDocument.CreateAttribute("xmlns");
                    attribute.Value = "http://Schema.xsd";
                    xmlDocument.DocumentElement.Attributes.Append(attribute);
                }
                StringBuilder modifiedXml = new StringBuilder();
                xmlDocument.Save(new StringWriter(modifiedXml));
                xml = modifiedXml.ToString();
                XmlSchemaSet schemaSet = new XmlSchemaSet();
                schemaSet.Add(null, new XmlTextReader(new StringReader(_schema.Trim()))); // _schema consists of the schema definition
                XmlReaderSettings settings = new XmlReaderSettings();
                settings.Schemas = schemaSet;
                settings.ValidationType = ValidationType.Schema;
                settings.ValidationEventHandler += new ValidationEventHandler(LogErrors);
                XmlReader reader = XmlReader.Create(new XmlTextReader(new StringReader(xml.Trim())), settings);
                while (reader.Read()) ;
 
            }
            catch (Exception e)
            {
                errorsExist = true;
            }
            return (!errorsExist);
        }
 
        private static void LogErrors(object sender, ValidationEventArgs args)
        {
            errorsExist = true;
        }

Open in new window

0
 
LVL 13

Expert Comment

by:Velio
ID: 20864632
also, replace line 7 with

if (xmlDocument.DocumentElement.Attributes.GetNamedItem("xmlns") != "http://Schema.xsd")

this will make sure you validate against your schema regardless of whether there's another one in the xml.

i feel curiously dirty after all this, i'm sure there's a more "proper" way of doing this, so i hope solving your problem is a more important than elegance :)
0
 
LVL 13

Expert Comment

by:Velio
ID: 20864640
i mean line 8.
0
 

Author Closing Comment

by:Vootan
ID: 31429380
I wonder if there is a more elegant way to do this.If yes, please let me know.
0
 

Author Comment

by:Vootan
ID: 20879782
I wonder if there is a more elegant way to do this.If yes, please let me know
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
Article by: Najam
Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Stellar Phoenix SQL Database Repair software easily fixes the suspect mode issue of SQL Server database. It is a simple process to bring the database from suspect mode to normal mode. Check out the video and fix the SQL database suspect mode problem.

601 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question