2009-02-21 22 views
11

Il seguente codice consente di convalidare un file XML con uno schema XSD.Convalida Xml utilizzando lo schema XSD

XmlReaderSettings settings = new XmlReaderSettings(); 
settings.Schemas.Add(null, xsdFilePath); 
settings.ValidationType = ValidationType.Schema; 
settings.ValidationEventHandler += new System.Xml.Schema.ValidationEventHandler(settings_ValidationEventHandler); 
XmlDocument document = new XmlDocument(); 
document.Load(xmlFilePath); 
XmlReader rdr = XmlReader.Create(new StringReader(document.InnerXml), settings); 

while (rdr.Read()) 
{ 

} 
isValid = true; 

Il ValidationEventHandler mi dice anche ciò che gli errori sono, ma non mi dice il 'dove' o 'su quale linea' si trovano. C'è un modo per ottenere il numero di riga in cui l'XML non riesce a essere convalidato?

risposta

28

Questo non dovrebbe fare ciò che cercate?

Creare un oggetto XmlReaderSettings e abilitare gli avvisi tramite tale oggetto.

Sfortunatamente, sembra che non ci sia modo di passare il proprio oggetto XmlReaderSettings a XmlDocument.Validate().
Invece, è possibile utilizzare una validazione XmlReader ed un XmlNodeReader di convalidare un esistente XmlDocument (utilizzando un XmlNodeReader con StringReader piuttosto che un XmlDocument)

XmlDocument x = new XmlDocument(); 
x.LoadXml(XmlSource); 

XmlReaderSettings settings = new XmlReaderSettings(); 
settings.CloseInput = true;  
settings.ValidationEventHandler += Handler; 

settings.ValidationType = ValidationType.Schema; 
settings.Schemas.Add(null, ExtendedTreeViewSchema); 
settings.ValidationFlags = 
    XmlSchemaValidationFlags.ReportValidationWarnings | 
XmlSchemaValidationFlags.ProcessIdentityConstraints | 
XmlSchemaValidationFlags.ProcessInlineSchema | 
XmlSchemaValidationFlags.ProcessSchemaLocation ; 

StringReader r = new StringReader(XmlSource); 

using (XmlReader validatingReader = XmlReader.Create(r, settings)) { 
     while (validatingReader.Read()) { /* just loop through document */ } 
} 

e il gestore:

private static void Handler(object sender, ValidationEventArgs e) 
{ 
     if (e.Severity == XmlSeverityType.Error || e.Severity == XmlSeverityType.Warning) 
      System.Diagnostics.Trace.WriteLine(
      String.Format("Line: {0}, Position: {1} \"{2}\"", 
       e.Exception.LineNumber, e.Exception.LinePosition, e.Exception.Message)); 
} 
+2

+1 Completamente mancato e.Exception.LineNumber e e.Exception.LinePosition. – Elroy

+0

Perché stai mettendo questo in un XmlDocument all'inizio? Non sembra fare nulla. –

+0

@JeremyHolovacs true, era solo una copia di una delle risposte del forum del 2007 (http://www.devnewsgroups.net/dotnetframework/t43762-catching-line-numbers-with-xmldocument-validate.aspx), e il seguente commento ha menzionato: "Funziona quando non uso' XmlDocument' e sostituisco 'XmlNodeReader' con ' StringReader' " – VonC

3

ValidationEventArgs .Message include riga/colonna nel suo testo.

ValidationEventArgs.Exception dispone di campi per riga e colonna.