By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
460,022 Members | 1,354 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 460,022 IT Pros & Developers. It's quick & easy.

XML Validating Reader and XmlSchemaException

P: n/a
Hello,

I am experimenting with this XmlValidatingReader and have a question
about how it is working (or not working as would be the case)

The sample documents and code are included at the end of the post. I am
using VS.net 2003, .Net 1.1, Win2k Server

I have a simple schema and a simple XML document.

The problem is with how I handle errors from the XmlValidatingReader, for
this, there are two options:

Option 1: set the ValidationEventHandler to a call back routine.
This works without an issue, if my XML document has two invalid element
values, the callback is called twice and the proper errors are reported.
No problems.

Output using option 1 with the callback:

Read: 'XmlDeclaration'. Name = 'xml', Value='version="1.0"
encoding="utf-8"'
Read: 'Element'. Name = 'Root', Value=''
Read: 'Element'. Name = 'Record', Value=''
Read: 'Element'. Name = 'TheElementInt', Value=''
Read: 'Text'. Name = '', Value='1ss3'
The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has an
invalid value according to its data type. An error occurred at , (4, 24).
Read: 'EndElement'. Name = 'TheElementInt', Value=''
Read: 'Element'. Name = 'TheElementString', Value=''
Read: 'Text'. Name = '', Value='abcdezxcvbasdasd'
The 'http://tempuri.org/TheSchema.xsd:TheElementString' element has an
invalid value according to its data type. An error occurred at , (5, 39).
Read: 'EndElement'. Name = 'TheElementString', Value=''
Read: 'EndElement'. Name = 'Record', Value=''
Read: 'EndElement'. Name = 'Root', Value=''
Option 2: Don't set the ValidationEventHandler. (I commented it out in
my sample)
By doing this the Read() method will toss a XmlSchemaException exception
in the event that a validation against the schema has failed. The
problem I seem to be encountering on this is it (the validating reader)
keeps throwing an exception referencing the first error every time I read
an element/endelement nodetype. I don't believe this is correct, is it?

Here is the output of my program for option 2. The first error
encountered is valid, 1ss3 is not an integer. However the error about my
string being to long is not reported. The remaining errors only ever
refer to the offending "TheElementInt" element.

Read: 'XmlDeclaration'. Name = 'xml', Value='version="1.0"
encoding="utf-8"'
Read: 'Element'. Name = 'Root', Value=''
Read: 'Element'. Name = 'Record', Value=''
Read: 'Element'. Name = 'TheElementInt', Value=''
Read: 'Text'. Name = '', Value='1ss3'
ERROR-->EndElement - TheElementInt:
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (4,
24).
ERROR-->Element - TheElementString:
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (5,
4).
Read: 'Text'. Name = '', Value='abcdezxcvbasdasd'
ERROR-->EndElement - TheElementString:
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (5,
39).
ERROR-->EndElement - Record:
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (6,
4).
ERROR-->EndElement - Root:
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (7,
3).
ERROR-->None - :
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (7,
8).
Why the difference in how the two items function?

Thanks in advance..

Craig B.

Here is the schema I am using.

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://tempuri.org/TheSchema.xsd"
elementFormDefault="qualified"
targetNamespace="http://tempuri.org/TheSchema.xsd" id="TheSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="unbounded" name="Record">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1"
name="TheElementInt" type="xs:int" />
<xs:element minOccurs="1" maxOccurs="1"
name="TheElementString">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Here is my sample XML file:

<?xml version="1.0" encoding="utf-8" ?>
<Root xmlns="http://tempuri.org/TheSchema.xsd">
<Record>
<TheElementInt>1ss3</TheElementInt>
<TheElementString>abcdezxcvbasdasd</TheElementString>
</Record>
</Root>

Here is the code I am using to validate (just throw it in a WindowsForms
project) There are no class level variables required.:

// Load the schema and return an instance of the XmlSchema Class
// to be added to the validating reader.
private System.Xml.Schema.XmlSchema GetTheSchema()
{
System.IO.FileStream fs;
System.Xml.Schema.XmlSchema xsd;

fs = new System.IO.FileStream(@"m:\Devcode.Net\ValidatorTes t
\TheSchema.xsd", System.IO.FileMode.Open);
xsd = System.Xml.Schema.XmlSchema.Read(fs, null);
fs.Close();
xsd.Compile(null);
return xsd;
}

// the guts of the matter
private void button1_Click(object sender, System.EventArgs e)
{
System.IO.FileStream fs = new System.IO.FileStream(@"m:\Devcode.Net
\ValidatorTest\Sample.xml", System.IO.FileMode.Open);
System.Xml.XmlTextReader xmlr = new System.Xml.XmlTextReader (fs);
System.Xml.XmlValidatingReader xvr = new
System.Xml.XmlValidatingReader(xmlr);

System.Xml.Schema.XmlSchema theSchema;
theSchema = GetTheSchema();

xvr.Schemas.Add (theSchema);
//xvr.ValidationEventHandler +=new
System.Xml.Schema.ValidationEventHandler(xvr_Valid ationEventHandler);
while (xvr.EOF == false)
{
try
{
xvr.Read();
switch (xvr.NodeType)
{
case System.Xml.XmlNodeType.Document:
case System.Xml.XmlNodeType.Element:
case System.Xml.XmlNodeType.EndElement:
case System.Xml.XmlNodeType.Text:
case System.Xml.XmlNodeType.XmlDeclaration:
case System.Xml.XmlNodeType.Entity:
case System.Xml.XmlNodeType.EntityReference:
case System.Xml.XmlNodeType.EndEntity:
case System.Xml.XmlNodeType.Comment:
case System.Xml.XmlNodeType.CDATA:
case System.Xml.XmlNodeType.Attribute:
System.Diagnostics.Debug.WriteLine
(string.Format ("Read: '{0}'. Name = '{1}', Value='{2}'", xvr.NodeType,
xvr.Name, xvr.Value));
break;
}
}
catch (System.Xml.Schema.XmlSchemaException xsex)
{
System.Diagnostics.Debug.WriteLine (string.Format
("ERROR-->{0} - {1}:{2}", xvr.NodeType, xvr.Name, xvr.Value));
System.Diagnostics.Debug.WriteLine ("ERROR-->" +
xsex.Message);
}
}
xvr.Close();
xmlr.Close();
}

private void xvr_ValidationEventHandler(object sender,
System.Xml.Schema.ValidationEventArgs e)
{
System.Diagnostics.Debug.WriteLine (e.Message);
}
Nov 12 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
In case where you did not hook up the event handler, the reader throws an
Exception after which the reader can not be used for further validation, if
you want all errors to be reported, always attach an event handler.

"Craig Beuker" <be**********@shaw.ca> wrote in message
news:Xn******************************@207.46.248.1 6...
Hello,

I am experimenting with this XmlValidatingReader and have a question
about how it is working (or not working as would be the case)

The sample documents and code are included at the end of the post. I am
using VS.net 2003, .Net 1.1, Win2k Server

I have a simple schema and a simple XML document.

The problem is with how I handle errors from the XmlValidatingReader, for
this, there are two options:

Option 1: set the ValidationEventHandler to a call back routine.
This works without an issue, if my XML document has two invalid element
values, the callback is called twice and the proper errors are reported.
No problems.

Output using option 1 with the callback:

Read: 'XmlDeclaration'. Name = 'xml', Value='version="1.0"
encoding="utf-8"'
Read: 'Element'. Name = 'Root', Value=''
Read: 'Element'. Name = 'Record', Value=''
Read: 'Element'. Name = 'TheElementInt', Value=''
Read: 'Text'. Name = '', Value='1ss3'
The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has an
invalid value according to its data type. An error occurred at , (4, 24).
Read: 'EndElement'. Name = 'TheElementInt', Value=''
Read: 'Element'. Name = 'TheElementString', Value=''
Read: 'Text'. Name = '', Value='abcdezxcvbasdasd'
The 'http://tempuri.org/TheSchema.xsd:TheElementString' element has an
invalid value according to its data type. An error occurred at , (5, 39).
Read: 'EndElement'. Name = 'TheElementString', Value=''
Read: 'EndElement'. Name = 'Record', Value=''
Read: 'EndElement'. Name = 'Root', Value=''
Option 2: Don't set the ValidationEventHandler. (I commented it out in
my sample)
By doing this the Read() method will toss a XmlSchemaException exception
in the event that a validation against the schema has failed. The
problem I seem to be encountering on this is it (the validating reader)
keeps throwing an exception referencing the first error every time I read
an element/endelement nodetype. I don't believe this is correct, is it?

Here is the output of my program for option 2. The first error
encountered is valid, 1ss3 is not an integer. However the error about my
string being to long is not reported. The remaining errors only ever
refer to the offending "TheElementInt" element.

Read: 'XmlDeclaration'. Name = 'xml', Value='version="1.0"
encoding="utf-8"'
Read: 'Element'. Name = 'Root', Value=''
Read: 'Element'. Name = 'Record', Value=''
Read: 'Element'. Name = 'TheElementInt', Value=''
Read: 'Text'. Name = '', Value='1ss3'
ERROR-->EndElement - TheElementInt:
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (4,
24).
ERROR-->Element - TheElementString:
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (5,
4).
Read: 'Text'. Name = '', Value='abcdezxcvbasdasd'
ERROR-->EndElement - TheElementString:
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (5,
39).
ERROR-->EndElement - Record:
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (6,
4).
ERROR-->EndElement - Root:
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (7,
3).
ERROR-->None - :
ERROR-->The 'http://tempuri.org/TheSchema.xsd:TheElementInt' element has
an invalid value according to its data type. An error occurred at , (7,
8).
Why the difference in how the two items function?

Thanks in advance..

Craig B.

Here is the schema I am using.

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://tempuri.org/TheSchema.xsd"
elementFormDefault="qualified"
targetNamespace="http://tempuri.org/TheSchema.xsd" id="TheSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="unbounded" name="Record">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1"
name="TheElementInt" type="xs:int" />
<xs:element minOccurs="1" maxOccurs="1"
name="TheElementString">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Here is my sample XML file:

<?xml version="1.0" encoding="utf-8" ?>
<Root xmlns="http://tempuri.org/TheSchema.xsd">
<Record>
<TheElementInt>1ss3</TheElementInt>
<TheElementString>abcdezxcvbasdasd</TheElementString>
</Record>
</Root>

Here is the code I am using to validate (just throw it in a WindowsForms
project) There are no class level variables required.:

// Load the schema and return an instance of the XmlSchema Class
// to be added to the validating reader.
private System.Xml.Schema.XmlSchema GetTheSchema()
{
System.IO.FileStream fs;
System.Xml.Schema.XmlSchema xsd;

fs = new System.IO.FileStream(@"m:\Devcode.Net\ValidatorTes t
\TheSchema.xsd", System.IO.FileMode.Open);
xsd = System.Xml.Schema.XmlSchema.Read(fs, null);
fs.Close();
xsd.Compile(null);
return xsd;
}

// the guts of the matter
private void button1_Click(object sender, System.EventArgs e)
{
System.IO.FileStream fs = new System.IO.FileStream(@"m:\Devcode.Net
\ValidatorTest\Sample.xml", System.IO.FileMode.Open);
System.Xml.XmlTextReader xmlr = new System.Xml.XmlTextReader (fs);
System.Xml.XmlValidatingReader xvr = new
System.Xml.XmlValidatingReader(xmlr);

System.Xml.Schema.XmlSchema theSchema;
theSchema = GetTheSchema();

xvr.Schemas.Add (theSchema);
//xvr.ValidationEventHandler +=new
System.Xml.Schema.ValidationEventHandler(xvr_Valid ationEventHandler);
while (xvr.EOF == false)
{
try
{
xvr.Read();
switch (xvr.NodeType)
{
case System.Xml.XmlNodeType.Document:
case System.Xml.XmlNodeType.Element:
case System.Xml.XmlNodeType.EndElement:
case System.Xml.XmlNodeType.Text:
case System.Xml.XmlNodeType.XmlDeclaration:
case System.Xml.XmlNodeType.Entity:
case System.Xml.XmlNodeType.EntityReference:
case System.Xml.XmlNodeType.EndEntity:
case System.Xml.XmlNodeType.Comment:
case System.Xml.XmlNodeType.CDATA:
case System.Xml.XmlNodeType.Attribute:
System.Diagnostics.Debug.WriteLine
(string.Format ("Read: '{0}'. Name = '{1}', Value='{2}'", xvr.NodeType,
xvr.Name, xvr.Value));
break;
}
}
catch (System.Xml.Schema.XmlSchemaException xsex)
{
System.Diagnostics.Debug.WriteLine (string.Format
("ERROR-->{0} - {1}:{2}", xvr.NodeType, xvr.Name, xvr.Value));
System.Diagnostics.Debug.WriteLine ("ERROR-->" +
xsex.Message);
}
}
xvr.Close();
xmlr.Close();
}

private void xvr_ValidationEventHandler(object sender,
System.Xml.Schema.ValidationEventArgs e)
{
System.Diagnostics.Debug.WriteLine (e.Message);
}

Nov 12 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.