Thursday, November 6, 2008

XML

If you are a .NET XML developer, hopefully you are already familiar with and using the XPathNavigator and XPathDocument whenever you can. This model for dealing with XML was introduced in .NET 1.0 as a powerful new alternative to working with the DOM.

The .NET Framework improves on this model with the introduction of XML readers, which employ a more practical "pull" model of smart data passing, as opposed to the impractical "push" method of previous parser models.

Tree-based parser – DOM

Event-driven parser – SAX - They simply parse the document and notify client applications about any tag they find along the way. Event-driven parsers don’t cache information and have an enviably small memory footprint.

The XML API available in the .NET Framework supports the XML DOM parsing model, but not the SAX model.

The .NET Framework offers a more effective way to parse XML documents in a read-only, noncached, forward-only manner. This new generation of parser presents a document reader and functions as a pull model, as opposed to the SAX’s push model.

An XML reader is a class that reads a source document node after node, proceeding from the root to the rightmost leaf of the XML tree via node-first visiting. The node-first algorithm prescribes that the reader first analyzes the root of a subtree and then recursively moves to its children in the order that they appear. The visiting order of the node-first algorithm coincides with the order in which XML nodes appear on a disk file.

The code snippet in Listing A shows some Visual Basic code that exploits the SAX services provided by the Microsoft MSXML 4.0 COM library.

The .NET Framework's support of readers instead of SAX parsers does not limit your programming power. But if you’re a fan of the SAX model, you can still set up a SAX parser using a .NET reader with little hassle. You have to create a new reader class that exposes events for each node found and that uses a reader to visit a document. This ability stems from the inherently greater flexibility of the pull model. While you can emulate the push model using pull-based components, you just can't build a pull model parser using a SAX parser.

XML Schema, XPath, XSLT, and - eventually - XQuery.

An XPath expression is composed of one to many location steps. Each location step evaluates to either a node set, or a value.

Each location step can itself be composed of three parts: an axis, a node test, and a predicate. The axis specifies a search direction and depth from the current node. The node test is the heart of the location step, and is the part that will be evaluated against nodes along that axis to determine whether they match the criteria. The predicate is optional, and allows you to specify assertions that will be evaluated against any nodes matching the node test to further filter the results.

Get There with XPathNavigator:

The truth is that, under the covers, SelectNodes is using XPathNavigator for you.

You can user XPathNavigator with :

  • XmlDocument
  • XmlDataDocument
  • XPathDocument

To perform a query with an XPathNavigator instance, you can call its Select method, passing in an XPath expression. What you get back is an XPathNodeIterator that allows you to step through the results. This is another lightweight object that allows you to obtain an XPathNavigator reference to each of the nodes that matched the query. Using these references, you can then either extract data from the nodes, or you can use the navigator to perform subsequent queries or navigation that will be done relative to the matching nodes.

The XPathDocument class is the best to use in .NET if you don't need to modify the contents of the document while processing it.

The first to be aware of is that if you're going to perform the same query a number of times, perhaps on a collection of documents, then the query will execute significantly faster if you pre-compile the expression.

You do this by calling the Compile method on the navigator, passing in an XPath expression as a string and getting back an instance of an XPathExpression object.

XmlDocument supports the W3C standards for XML document management (the XML DOM model), plus useful additional features that make it easier to access the contents. The XmlDataDocument is designed to provide a bridge between XML and relational data by allowing the content to be accessed as a DataSet instance as well as a standard XML document. The XPathDocument is a fast and efficient document store designed to be accessed only using XPath methods and the XPathNavigator (although the XPathNavigator can be used over any of the three document stores).

XSD:

There are three ways to validate XML files: XSD Schema, DTD and Relax NG. In .NET XSD Schema is the preferred way to validate XML files.

If the Mydata.xsd file is not valid XML, MSXML will ignore it and validate for well-formed XML only. To avoid this type of outcome, its a good practice to always validate your schema files first prior to attempting to use them in validation of other documents.

targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"

elementFormDefault="qualified">

xmlns:xs="http://www.w3.org/2001/XMLSchema"

indicates that the elements and data types used in the schema come from the "http://www.w3.org/2001/XMLSchema" namespace. It also specifies that the elements and data types that come from the "http://www.w3.org/2001/XMLSchema" namespace should be prefixed with xs:

targetNamespace="http://www.w3schools.com"

indicates that the elements defined by this schema (note, to, from, heading, body.) come from the "http://www.w3schools.com" namespace.

xmlns="http://www.w3schools.com"

indicates that the default namespace is "http://www.w3schools.com".

elementFormDefault="qualified"

indicates that any elements used by the XML instance document which were declared in this schema must be namespace qualified.

Validation depends on whether the schema is deterministic or non-deterministic.

A deterministic schema is a schema that is not ambiguous. This means that when MSXML parses and loads the schema into the Schema Object Model (SOM), it can determine the sequence in which elements should occur for an XML document to be validated against the schema.

It is possible for an XML Schema to be ambiguous, or non-deterministic. A schema is non-deterministic if the parser is unable to clearly determine the structure to validate with the schema. When validation is attempted on a non-deterministic schema, the parser generates an error.

Validation event handler

The ValidationEventHandler event is used to define an event handler for receiving the notification about XSD schema validation errors. The validation errors and warnings are reported through the ValidationEventHandler call-back function. If any validation error occurs, an exception is thrown, and the XmlValidatingReader cannot be restarted.

Microsoft .NET framework classes support the W3C XML schema recommendation. The classes used to validate the XML document are XmlTextReader, XmlSchemaCollection, and XmlValidatingReader. The sequence of steps to validate an XML document is given as follows:

1. The ValidationHandler event handler method is defined.

2. The XSD schema is being parsed using XmlTextReader class.

3. The parsed schema is added to the schema collection using XmlSchemaCollection class.

4. The schema collection is associated with XmlValidatingReader class.

5. The event handler method is associated with XmlValidatingReader class.

6. XmlValidatingReader class validates the XML document using the namespace URI specified when the schema was added to the collection.

 using System;

using System.Collections;

using System.Data;

using System.IO;

using System.Xml;

using System.Xml.Schema;

using System.Text;

public class XMLValidator

{

// Validation Error Count

static int ErrorsCount = 0;

// Validation Error Message

static string ErrorMessage = "";

public static void ValidationHandler(object sender,

ValidationEventArgs args)

{

ErrorMessage = ErrorMessage + args.Message + "\r\n";

ErrorsCount ++;

}

public void Validate(string strXMLDoc)

{

try

{

// Declare local objects

XmlTextReader tr = null;

XmlSchemaCollection xsc = null;

XmlValidatingReader vr = null;

// Text reader object

tr = new XmlTextReader(urlpath);

xsc = new XmlSchemaCollection();

xsc.Add(null, tr);

// XML validator object

vr = new XmlValidatingReader( strXMLDoc,

XmlNodeType.Document, null);

vr.Schemas.Add(xsc);

// Add validation event handler

vr.ValidationType = ValidationType.Schema;

vr.ValidationEventHandler +=

new ValidationEventHandler(ValidationHandler);

// Validate XML data

while(vr.Read());

vr.Close();

// Raise exception, if XML validation fails

if (ErrorsCount > 0)

{

throw new Exception(ErrorMessage);

}

// XML Validation succeeded

Console.WriteLine("XML validation succeeded.\r\n");

}

catch(Exception error)

{

// XML Validation failed

Console.WriteLine("XML validation failed." + "\r\n" +

"Error Message: " + error.Message);

}

}

}

http://aspalliance.com/941_Validating_XML_Files_Against_XSD_Schemas_in_NET_1x_and_20.2

2.0

Read the XML file content as Stream, TextReader or XmlReader.

2. Read the Schema file content as Stream, TextReader or XmlReader.

3. Create a new instance of XmlSchema object.

4. Set XmlSchema object by calling XmlSchema.Read() method and passing the content of Schema file and ValidationEventHandler method address to it.

5. Create a new instance of XmlReaderSettings object.

6. Set ValidationType for XmlReaderSettings object to Schema.

7. Add your XmlSchema object to XmlReaderSettings Schemas collection by calling its Schemas.Add() method.

8. Add your ValidationEventHandler method address to XmlValidationReader's ValidationEventHandler handler.

9. Create a new instance of XmlReader object and pass your XML file content (as Stream or a Reader object) and XmlReaderSettings object to it.

10. Call Read() method of the Reader or Stream object to contain your XML file content in a loop to parse and validate it completely.

11. Add your logic to ValidationEventHandler method you created to implement what you want to be done in the validation process.

1.0

In 1.x you had to follow these steps to validate an XML file against an XSD Schema file.

1. Read XML file content as String, XmlTextReader or Stream.

2. Read Schema file content as Stream, TextReader or XmlReader.

3. Create a new instance of the XmlSchema object.

4. Set XmlSchema object by calling the XmlSchema.Read() method and passing the content of the Schema file and ValidationEventHandler method address to it.

5. Create a new instance of XmlValidationReader object.

6. Set ValidationType for XmlValidationReader object to Schema.

7. Add your XmlSchema object to XmlValidationReader Schemas collection by calling its Schemas.Add() method.

8. Add your ValidationEventHandler method address to XmlValidationReader's ValidationEventHandler handler.

9. Call Read() method of the Reader or Stream object to contain your XML file content in a loop to parse and validate it completely.

10. Add your logic to the ValidationEventHandler method you created to implement what you want to be done in the validation process.

No comments: