Article
Back to Basics: XML In .NET
Validating XML in .NET
Remember those schema files? Using the XmlValidatingReader class, we can easily validate an XML file against a schema file. However, there are a few other classes we have to use first.
We can point the XmlValidatingReader object towards the schema files we wish to use, by filling an XmlSchemaCollection with our schema files:
XmlSchemaCollection xsdCollection = new XmlSchemaCollection();
xsdCollection.Add("schemafile", "schema.xsd");
In this example, we're using the schema contained in the file schema.xsd.
The actual XmlValidatingReader class takes an XmlReader in its constructor. Consequently, we need to create and fill an XmlTextReader with the XML file we wish to validate:
XmlTextReader reader;
XmlValidatingReader validatingReader;
reader = new XmlTextReader("foo.xml");
validatingReader = new XmlValidatingReader(reader);
Then, we add our schemaCollection to the schemas we wish the validation reader to use:
validatingReader.Schemas.Add(xsdCollection);
If an error is found by the validator, an event is fired. We need to catch this event by creating an event handler, and code our response to the errors:
validatingReader.ValidationEventHandler += new ValidationEventHandler(validationCallBack);
public void validationCallBack (object sender, ValidationEventArgs args)
{
Response.Write("Error:" + args.Message);
}
Finally, we can validate our file using the Read method on the validating reader. We could actually read and process the nodes in the file as we did before, but, for the purposes of this example, we'll just use an empty while loop to step through the file, validating it as we go:
while (validatingReader.Read()){}
As errors are found during file processing, the event we catch and handle through the validationCallBack method will fire.
Writing XML in .NET
Now that we have a good understanding of how to read and validate an XML file, we can move on to writing XML.
Writing XML is made very painless by the XmlTextWriter class. Again, taking a forward-only approach, we can build our XML files from different node types, which are output in order.
To begin, we need to create an instance of the class:
XmlTextWriter writer = new XmlTextWriter("newfoo.xml", null);
The second parameter, which, here, is set to null, allows us to specify the encoding format to use on our XML file. Setting it to null produces a standard UTF-8 encoded XML file without an encoding attribute on the document element.
We can now proceed to start writing elements and attributes using our code, comprised of the methods exposed in the XmlTextWriter. Let us write our earlier CD catalogue example:
<catalog>
<cd>
<title>The Bends</title>
<artist>Radiohead</artist>
<tracks>
<track name="Street Spirit "/>
</tracks>
</cd>
</catalog>
Our first line is the element catalog. We use the WriteStartElement method to write this to the writer:
writer.WriteStartElement("catalog");
Notice that we don't want to close this element until we've written our CD elements. Thus, the next node we wish to add is an opening CD element:
writer.WriteStartElement("cd");
We now have a title element (<title>The Bends</title>). As before, we write a start element, but this type will differ because we have a specific value we wish to use. As we have no attributes on the title element, we can use the WriteElementString method:
writer.WriteElementString("title", "The Bends");
writer.WriteElementString("artist", "Radiohead");
writer.WriteStartElement("tracks");
Now we've reached an element, track, with an attribute, name. We first need to write the start of the element, then write the attributes, and finally, close our element:
writer.WriteStartElement("track");
writer.WriteAttributeString("name", "Street Spirit");
writer.WriteEndElement();
Notice how we don't need to say which element we wish to close, because the writer will automatically write the closing tag for the last-opened element, which, in this case, is track.
We can now close our remaining elements in the same fashion:
writer.WriteEndElement();
writer.WriteEndElement();
Finally, we need to "flush" the writer, or, in other words, to output the information we've requested to our XML file, then close the writer to free our file and resources:
writer.Flush()
writer.Close()
Summary
So completes this introduction to XML and its use within .NET. Hopefully, the world of XML no longer seems as intimidating as you might have originally thought, and you're now ready to harness its power for your next project.