none
How do I validate an XmlDocument (C# 3.5)?? RRS feed

  • Question

  • Hello,

    I really need some help validating an XmlDocument.  Unfortunately, this XmlDocument is an in-memory object and needs to be validated before it is ever saved to the file system.  However, every method I've seen for validating XmlDocuments requires pulling the document from the file system and not memory, so these are unusable.  My schema is on the file system, so that is OK, but solutions that require saving the XmlDocument first will not work.

    Disclaimer:  The schema and xml here were created for this exercise.  They have not been compiled, so they may be off a bit.  It's the validation methodology that I'm really concerned with though.  So, if you need to tweak the examples to make it work, that is fine....as long as the XmlDocument is validated from memory and not the file system.


    My schema looks like this  (saved as FullName.xsd)...

    Code Snippet

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema xmlns="http://me.com/FullName" xmlns:qcddcs="http://me.com/FullName" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="FullName">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="FirstName" type="xs:string" />
            <xs:element name="LastName" type="xs:string" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>



    My XmlDocument is created like this...

    Code Snippet

    XmlDocument doc = new XmlDocument();
    XmlElement fullName, firstName, lastName;

    // fullName
    fullName = doc.CreateElement("FullName");
    doc.AppendChild(fullName);

    // firstName
    firstName = doc.CreateElement("FirstName");
    firstName.InnerText = "Bob";
    fullName.AppendChild(firstName);

    // docDate
    lastName = doc.CreateElement("LastName");
    lastName.InnerText = "Barker";
    fullName.AppendChild(lastName);



    // Validate here.  But how??

    bool isValid = ValidateXML(doc);


    if (isValid)
    {

        // Save once it's been validated

    }





    Again, I need to validate the XmlDocument I just created without ever saving it to the file system.

    Can somebody please help me to achieve this? 

    Ideally, I need just a method that returns BOOL instead of throwing exceptions to an event handler.

    Also, this needs to be in C# 3.5 (not using deprecated code!).

    Thanks very much!!
    Friday, June 20, 2008 10:08 PM

Answers

  • That's right. You do not need to call the XmlReader and stuff since your document is being created differently. Omit the XmlReader stuff, create a validation handler (you can copy from the article) and call validate. One more thing - you need to somehow associate schemas with your XmlDocument. You do that using XmlDocument Schemas property. Here is the pseudo-code (xmlDoc is the doc you created earlier):

    Code Snippet

     

    ...

    xmlDoc.Schemas.Add(("http://www.contoso.com/books", "contosoBooks.xsd"); //add schema

    xmlDoc.Validate(new ValidationEventHandler(ValidationEventHandler));

    ...

     

    // Validation event handler

    public static void ValidationHandler(object sender, ValidationEventArgs vargs)

    {

    ...

    }

     

     

    Pawel

    Monday, June 23, 2008 5:22 PM
    Moderator

All replies

  • You can use Validate method from XmlDocument - here is more details on how to do that:

     

    http://msdn.microsoft.com/en-us/library/ms162371.aspx

     

    Pawel

     

    Friday, June 20, 2008 10:58 PM
    Moderator
  • Thanks, but I had already seen that link and it is not helpful.  My question specifies that I need to validate an XmlDocument from memory and NOT from the file system (like the link describes).

    Does somebody have a useful answer please?

    Thanks!
    Monday, June 23, 2008 4:31 PM
  • I assume that your document has been somehow built and is already in memory. Now you can use

    XmlDocument Validate method to validate the document and this is what the article describes. In the article they read the document from disk indeed but it is only to have an in-memory document. How you build your document is not relevant as far as you use Validate from XmlDocument class method.

     

    Pawel

    Monday, June 23, 2008 4:36 PM
    Moderator
  • So, would I just omit the XmlReader section?
    After I do that, do I just call Validate and then check the value of the ValidationEventHandler?


    Code Snippet


    XmlReaderSettings settings = new XmlReaderSettings(); settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd"); settings.ValidationType = ValidationType.Schema;



    // Omit?
    XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);
    XmlDocument document = new XmlDocument();
    document.Load(reader);
    // Omit?



    ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationEventHandler);
    document.Validate(eventHandler);


    Monday, June 23, 2008 5:09 PM
  • That's right. You do not need to call the XmlReader and stuff since your document is being created differently. Omit the XmlReader stuff, create a validation handler (you can copy from the article) and call validate. One more thing - you need to somehow associate schemas with your XmlDocument. You do that using XmlDocument Schemas property. Here is the pseudo-code (xmlDoc is the doc you created earlier):

    Code Snippet

     

    ...

    xmlDoc.Schemas.Add(("http://www.contoso.com/books", "contosoBooks.xsd"); //add schema

    xmlDoc.Validate(new ValidationEventHandler(ValidationEventHandler));

    ...

     

    // Validation event handler

    public static void ValidationHandler(object sender, ValidationEventArgs vargs)

    {

    ...

    }

     

     

    Pawel

    Monday, June 23, 2008 5:22 PM
    Moderator
  • Create and populate your XmlDocument instance. Then add schemas to its Schemas property. Then call the Validate method with your ValidationEventHandler (or don't pass a ValidationEventHandler and instead handle the excpetion the Validate method then throws if the document is not valid).

    Monday, June 23, 2008 5:23 PM
  • Thank you both for your help.

    I won't get the chance to try this code until later today, but I'll follow up with any questions.
    Monday, June 23, 2008 5:44 PM
  • OK.  That worked.  I'm all set.

    Here is my solution...


    Code Snippet

    XmlDocument xmlDoc = new XmlDocument();

    xmlDoc.Schemas.Add("http://me.com/FullName", "FullName.xsd");
              
    XmlElement fullName, firstName, lastName;


    // fullName
    fullName = doc.CreateElement("FullName");
    doc.AppendChild(fullName);

    // firstName
    firstName = doc.CreateElement("FirstName");
    firstName.InnerText = "Bob";
    fullName.AppendChild(firstName);

    // docDate
    lastName = doc.CreateElement("LastName");
    lastName.InnerText = "Barker";
    fullName.AppendChild(lastName);


    // Begin validation
    XmlValidator validator = new XmlValidator(xmlDoc);
    if (! validator.HasValidXML)
    {

    // Handle issue

    }


    ::::::::::::::::::::


    private class XmlValidator
    {

    public bool HasValidXML { get; set; }


         public XmlValidator(XmlDocument xmlDoc)
         {

    // Wire handler

    ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationEventHandler);

    // Initialize property

              this.HasValidXML = true;


    // Validate XML

              xmlDoc.Validate(eventHandler);
         }

         private void ValidationEventHandler(object sender, ValidationEventArgs e)
         {
             this.HasValidXML = false;
         }
    }


    Thanks again!

    Monday, June 23, 2008 11:28 PM