2009-02-21 46 views
11

El siguiente código me ayuda a validar un archivo XML con un esquema XSD.Validación de Xml con el esquema 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; 

El ValidationEventHandler también me dice lo que los errores son, pero no me dice sobre 'dónde' o 'en la que la línea' que se encuentran. ¿Hay alguna manera de obtener el número de línea donde no se valida el XML?

Respuesta

28

¿No haría esto lo que está buscando?

Cree un objeto XmlReaderSettings y active las advertencias a través de ese objeto.

Desafortunadamente, parece que no hay forma de pasar su propio objeto XmlReaderSettings a a XmlDocument.Validate().
su lugar, puede utilizar una validación XmlReader y un XmlNodeReader para validar una ya existente XmlDocument (utilizando un XmlNodeReader con StringReader en lugar de 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 */ } 
} 

y el manejador:

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 Totalmente perdido e.Exception.LineNumber y e.Exception.LinePosition. – Elroy

+0

¿Por qué estás poniendo esto en un XmlDocument al principio? No parece hacer nada. –

+0

@JeremyHolovacs cierto, fue solo una copia de una de las respuestas del foro de 2007 (http://www.devnewsgroups.net/dotnetframework/t43762-catching-line-numbers-with-xmldocument-validate.aspx), y el siguiente comentario mencionó: "Funciona cuando elimino el' XmlDocument' y reemplazo 'XmlNodeReader' con ' StringReader' " – VonC

3

ValidationEventArgs .Message incluye línea/columna en su texto.

ValidationEventArgs.Exception tiene campos para línea y columna.

Cuestiones relacionadas