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

XmlValidating Reader and XmlNodes

P: n/a
Is there a way to get the current XmlNode from the reader while in the
validation event handler? What I'd like to do is display the error message
along with the name of its parent node.

In my XML format, there are parent nodes named differently with some of the
same names for child nodes, so when I get an error message that references
the 'LOGICALPOCKET' node that could be under more than one different parent
node. I need to be able to tell the user which parent node it's under.

Thanks,
Todd
Nov 12 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a


Todd Bright wrote:
Is there a way to get the current XmlNode from the reader while in the
validation event handler? What I'd like to do is display the error message
along with the name of its parent node.


You could store the information while using the reader, here is a quick
hack example:

using System;
using System.Xml;
using System.Xml.Schema;

public class Test2005032401 {
private bool valid;
private XmlValidatingReader xmlValidator;
private string currentElementName;
private string parentElementName;

public static void Main (string[] args) {
new Test2005032401(args[0]);
}

public Test2005032401 (string xmlURL) {
xmlValidator = new XmlValidatingReader(new XmlTextReader(xmlURL));
xmlValidator.ValidationEventHandler += new
ValidationEventHandler(ValidationHandler);

valid = true;
Console.WriteLine("Validation starts:");

currentElementName = parentElementName = "";

while (xmlValidator.Read()) {
if (xmlValidator.NodeType == XmlNodeType.Element) {
parentElementName = currentElementName;
currentElementName = xmlValidator.Name;
}
}

Console.WriteLine("Validation is finished: " + (valid ? "XML is
valid" : "XML is not valid") + ".");
}

public void ValidationHandler (object sender, ValidationEventArgs args) {
valid = false;
Console.WriteLine("Validation error: {0}: current element is: {1},
parent element: {2}.", args.Message, currentElementName, parentElementName);
}

}

--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 12 '05 #2

P: n/a
That would be very ugly code because there are parent nodes that have child
nodes with the same name. I would have to look for the names of the parent
nodes and keep track of my own position within the reader. Since the format
of this XML could change, I don't want to put anything related to node names
or strings in the code. Here is an example of what I'm talking about:

<CONFIG>
<PARENT1>
<LOGICALPOCKET>0</LOGICALPOCKET>
<PHYSPOCKET>1</PHYSPOCKET>
...
</PARENT1>
<PARENT2>
<LOGICALPOCKET>0</LOGICALPOCKET>
<PHYSPOCKET>1</PHYSPOCKET>
...
</PARENT2>
</CONFIG>

Is there no way to get the current or parent XmlNode object from an
XmlReader (or XmlValidatingReader)???
"Martin Honnen" wrote:


Todd Bright wrote:
Is there a way to get the current XmlNode from the reader while in the
validation event handler? What I'd like to do is display the error message
along with the name of its parent node.


You could store the information while using the reader, here is a quick
hack example:

using System;
using System.Xml;
using System.Xml.Schema;

public class Test2005032401 {
private bool valid;
private XmlValidatingReader xmlValidator;
private string currentElementName;
private string parentElementName;

public static void Main (string[] args) {
new Test2005032401(args[0]);
}

public Test2005032401 (string xmlURL) {
xmlValidator = new XmlValidatingReader(new XmlTextReader(xmlURL));
xmlValidator.ValidationEventHandler += new
ValidationEventHandler(ValidationHandler);

valid = true;
Console.WriteLine("Validation starts:");

currentElementName = parentElementName = "";

while (xmlValidator.Read()) {
if (xmlValidator.NodeType == XmlNodeType.Element) {
parentElementName = currentElementName;
currentElementName = xmlValidator.Name;
}
}

Console.WriteLine("Validation is finished: " + (valid ? "XML is
valid" : "XML is not valid") + ".");
}

public void ValidationHandler (object sender, ValidationEventArgs args) {
valid = false;
Console.WriteLine("Validation error: {0}: current element is: {1},
parent element: {2}.", args.Message, currentElementName, parentElementName);
}

}

--

Martin Honnen
http://JavaScript.FAQTs.com/

Nov 12 '05 #3

P: n/a


Todd Bright wrote:
That would be very ugly code because there are parent nodes that have child
nodes with the same name. I would have to look for the names of the parent
nodes and keep track of my own position within the reader. Since the format
of this XML could change, I don't want to put anything related to node names
or strings in the code. Here is an example of what I'm talking about:

<CONFIG>
<PARENT1>
<LOGICALPOCKET>0</LOGICALPOCKET>
<PHYSPOCKET>1</PHYSPOCKET>
...
</PARENT1>
<PARENT2>
<LOGICALPOCKET>0</LOGICALPOCKET>
<PHYSPOCKET>1</PHYSPOCKET>
...
</PARENT2>
</CONFIG>

Is there no way to get the current or parent XmlNode object from an
XmlReader (or XmlValidatingReader)???


The members of XmlValidatingReader are here:
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXmlValidatingReaderMembersTopic.asp>
so you can as I suggested and showed you in the previous post at any
time read out the current node type the reader is positioned on with the
NodeType property, read out the current node name with the Name
property. You would then only need an additional variable which stores
the node name of the parent element. I don't know why code doing that is
ugly because your original post said: "I'd like to do is display the
error message along with the name of its parent node". That is what my
code example does. Of course you need a variable to store the node name
but why a variable is ugly I don't understand.

As for an XmlNode instance the reader is a pull based mechanism to read
through an XML document, it doesn't create XmlNode instances at all, if
you need them you would need to create them yourself which is obviously
more work then just storing the node name of the parent element.
--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 12 '05 #4

P: n/a
Here is a replacement for the loop. Have to take your depth into account,
otherwise parent name will ALWAYS be replaced even if you've traversed to a
node at the same level (that's not the current node's parent).

I looked for a way to tell the user what XSD type the node in error is
declared as, but to no avail. Surely that would be helpful information when
debugging. I think it would be worth while for the developer to have more
control over the validation and to have access to the underlying XSD elements
when an error occurs. Anyone know if that is possible???

string currentNodeName;
int prevDepth = 0;
parentNodeName = currentNodeName = reader.Name;
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Depth > prevDepth)
{
parentNodeName = currentNodeName;
currentNodeName = reader.Name;
prevDepth = reader.Depth;
}
else if (reader.Depth < prevDepth)
{
parentNodeName = currentNodeName = reader.Name;
prevDepth = reader.Depth;
}
}
}
reader.Close();

"Martin Honnen" wrote:


Todd Bright wrote:
That would be very ugly code because there are parent nodes that have child
nodes with the same name. I would have to look for the names of the parent
nodes and keep track of my own position within the reader. Since the format
of this XML could change, I don't want to put anything related to node names
or strings in the code. Here is an example of what I'm talking about:

<CONFIG>
<PARENT1>
<LOGICALPOCKET>0</LOGICALPOCKET>
<PHYSPOCKET>1</PHYSPOCKET>
...
</PARENT1>
<PARENT2>
<LOGICALPOCKET>0</LOGICALPOCKET>
<PHYSPOCKET>1</PHYSPOCKET>
...
</PARENT2>
</CONFIG>

Is there no way to get the current or parent XmlNode object from an
XmlReader (or XmlValidatingReader)???


The members of XmlValidatingReader are here:
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXmlValidatingReaderMembersTopic.asp>
so you can as I suggested and showed you in the previous post at any
time read out the current node type the reader is positioned on with the
NodeType property, read out the current node name with the Name
property. You would then only need an additional variable which stores
the node name of the parent element. I don't know why code doing that is
ugly because your original post said: "I'd like to do is display the
error message along with the name of its parent node". That is what my
code example does. Of course you need a variable to store the node name
but why a variable is ugly I don't understand.

As for an XmlNode instance the reader is a pull based mechanism to read
through an XML document, it doesn't create XmlNode instances at all, if
you need them you would need to create them yourself which is obviously
more work then just storing the node name of the parent element.
--

Martin Honnen
http://JavaScript.FAQTs.com/

Nov 12 '05 #5

P: n/a


Todd Bright wrote:

I looked for a way to tell the user what XSD type the node in error is
declared as, but to no avail. Surely that would be helpful information when
debugging.


The XmlValidatingReader has a property named SchemaType that holds the
type. Is that what you are looking for?

--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 12 '05 #6

P: n/a
I wanted to display the datatype that the node is declared as in the XSD file
(string, short, int,...) But I couldn't find a way to link the reader and
the XSD schema up so that I could get to that information when an error
occurs. Seems that when an error such as a value out of range occurs, by the
time the validation error routine is called it is on the end element of
whatever node the error occured in.

"Martin Honnen" wrote:


Todd Bright wrote:

I looked for a way to tell the user what XSD type the node in error is
declared as, but to no avail. Surely that would be helpful information when
debugging.


The XmlValidatingReader has a property named SchemaType that holds the
type. Is that what you are looking for?

--

Martin Honnen
http://JavaScript.FAQTs.com/

Nov 12 '05 #7

P: n/a


Todd Bright wrote:
I wanted to display the datatype that the node is declared as in the XSD file
(string, short, int,...) But I couldn't find a way to link the reader and
the XSD schema up so that I could get to that information when an error
occurs. Seems that when an error such as a value out of range occurs, by the
time the validation error routine is called it is on the end element of
whatever node the error occured in.


I have now tried to store the SchemaType property the reader exposes and
access it in the validation event handler as follows:

using System;
using System.Xml;
using System.Xml.Schema;

public class Test2005032601 {
private bool valid;
private object currentSchemaType;

public static void Main (string[] args) {
Test2005032601 test = new Test2005032601();
System.Threading.Thread.CurrentThread.CurrentCultu re = new
System.Globalization.CultureInfo("en-US");
test.Validate(args[0]);
}

public void Validate (string xmlURL) {
XmlValidatingReader xmlValidator = new XmlValidatingReader(new
XmlTextReader(xmlURL));
xmlValidator.ValidationEventHandler += new
ValidationEventHandler(ValidationHandler);
valid = true;
currentSchemaType = null;
Console.WriteLine("Starting validation of {0}:", xmlURL);
while (xmlValidator.Read()) {
if (xmlValidator.NodeType == XmlNodeType.Element ||
xmlValidator.NodeType == XmlNodeType.Attribute) {
currentSchemaType = xmlValidator.SchemaType;
}
}
xmlValidator.Close();
Console.WriteLine("Validation finished: XML document is {0}.",
valid ? "valid" : "not valid");
}

void ValidationHandler (object sender, ValidationEventArgs args) {
if (args.Severity == XmlSeverityType.Error) {
valid = false;
}
Console.WriteLine("Validation {0}: {1}.", args.Severity, args.Message);
if (currentSchemaType != null) {
if (currentSchemaType is XmlSchemaDatatype) {
XmlSchemaDatatype dataType = (XmlSchemaDatatype)currentSchemaType;
Console.WriteLine("Type should be {0}, .NET type {1}.",
dataType, dataType.ValueType);
}
}
}

}

That then gives information alike

Type should be System.Xml.Schema.Datatype_NCName, .NET type System.String.

when a type of an element or attribute is not correct. Unfortunately
classes like System.Xml.Schema.Datatype_NCName do not seem to be part of
the public classes the .NET framework exposes, there is only the
abstract class XmlSchemaDatatype that is documented.
--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 12 '05 #8

P: n/a
In all my gallavanting around the schema classes in the framework, you'd
think I would've seen XmlSchemaDataType. Thanks again. Now this gives me
exactly what I wanted to show to the user in the case of a type "mismatch"...
the parent node (table name), current node (field name) and corresponding
schema node data type. This XML is being used as a "database" of sorts for a
disconnected client.

"Martin Honnen" wrote:


Todd Bright wrote:
I wanted to display the datatype that the node is declared as in the XSD file
(string, short, int,...) But I couldn't find a way to link the reader and
the XSD schema up so that I could get to that information when an error
occurs. Seems that when an error such as a value out of range occurs, by the
time the validation error routine is called it is on the end element of
whatever node the error occured in.


I have now tried to store the SchemaType property the reader exposes and
access it in the validation event handler as follows:

using System;
using System.Xml;
using System.Xml.Schema;

public class Test2005032601 {
private bool valid;
private object currentSchemaType;

public static void Main (string[] args) {
Test2005032601 test = new Test2005032601();
System.Threading.Thread.CurrentThread.CurrentCultu re = new
System.Globalization.CultureInfo("en-US");
test.Validate(args[0]);
}

public void Validate (string xmlURL) {
XmlValidatingReader xmlValidator = new XmlValidatingReader(new
XmlTextReader(xmlURL));
xmlValidator.ValidationEventHandler += new
ValidationEventHandler(ValidationHandler);
valid = true;
currentSchemaType = null;
Console.WriteLine("Starting validation of {0}:", xmlURL);
while (xmlValidator.Read()) {
if (xmlValidator.NodeType == XmlNodeType.Element ||
xmlValidator.NodeType == XmlNodeType.Attribute) {
currentSchemaType = xmlValidator.SchemaType;
}
}
xmlValidator.Close();
Console.WriteLine("Validation finished: XML document is {0}.",
valid ? "valid" : "not valid");
}

void ValidationHandler (object sender, ValidationEventArgs args) {
if (args.Severity == XmlSeverityType.Error) {
valid = false;
}
Console.WriteLine("Validation {0}: {1}.", args.Severity, args.Message);
if (currentSchemaType != null) {
if (currentSchemaType is XmlSchemaDatatype) {
XmlSchemaDatatype dataType = (XmlSchemaDatatype)currentSchemaType;
Console.WriteLine("Type should be {0}, .NET type {1}.",
dataType, dataType.ValueType);
}
}
}

}

That then gives information alike

Type should be System.Xml.Schema.Datatype_NCName, .NET type System.String.

when a type of an element or attribute is not correct. Unfortunately
classes like System.Xml.Schema.Datatype_NCName do not seem to be part of
the public classes the .NET framework exposes, there is only the
abstract class XmlSchemaDatatype that is documented.
--

Martin Honnen
http://JavaScript.FAQTs.com/

Nov 12 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.