2009-06-17 10 views
5

Necesito validar un archivo XML con un esquema. El archivo XML se está generando en código y antes de guardarlo necesito validarlo para que sea correcto.¿Por qué falla mi validación XML en comparación con su esquema?

He reducido el problema a sus elementos más básicos, pero tengo un problema.

XML:

<?xml version="1.0" encoding="utf-16"?> 
<MRIDSupportingData xmlns="urn:GenericLabData"> 
    <MRIDNumber>MRIDDemo</MRIDNumber> 
    <CrewMemberIdentifier>1234</CrewMemberIdentifier> 
    <PrescribedTestDate>1/1/2005</PrescribedTestDate> 
</MRIDSupportingData> 

esquema:

<?xml version="1.0" encoding="utf-16"?> 
<xs:schema xmlns="urn:GenericLabData" targetNamespace="urn:GenericLabData" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <xs:element name="MRIDSupportingData"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="MRIDNumber" type="xs:string" /> 
     <xs:element minOccurs="1" name="CrewMemberIdentifier" type="xs:string" /> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

ValidationCode:. (Este código es de una sencilla aplicación que escribí para probar la lógica de validación Los archivos XML y XSD se almacenan en el disco y se están leyendo desde allí. En la aplicación actual, el archivo XML ya estaría en la memoria como un objeto XmlDocument y el XSD se leería desde un servidor web interno.)

private void Validate() 
{ 
    XmlReaderSettings settings = new XmlReaderSettings(); 
    settings.ValidationType = ValidationType.Schema; 
    //settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema; 
    //settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation; 
    //settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings; 
    settings.ValidationEventHandler += new ValidationEventHandler(OnValidate); 

    XmlSchemaSet schemas = new XmlSchemaSet(); 
    settings.Schemas = schemas; 
    try 
    { 
    schemas.Add(null, schemaPathTextBox.Text); 
    using (XmlReader reader = XmlReader.Create(xmlDocumentPathTextBox.Text, settings)) 
    { 
     validateText.AppendLine("Validating..."); 
     while (reader.Read()) ; 
     validateText.AppendLine("Finished Validating"); 
     textBox1.Text = validateText.ToString(); 
    } 
    } 
    catch (Exception ex) 
    { 
    textBox1.Text = ex.ToString(); 
    } 

} 

StringBuilder validateText = new StringBuilder(); 
private void OnValidate(object sender, ValidationEventArgs e) 
{ 
    switch (e.Severity) 
    { 
    case XmlSeverityType.Error: 
     validateText.AppendLine(string.Format("Error: {0}", e.Message)); 
     break; 
    case XmlSeverityType.Warning: 
     validateText.AppendLine(string.Format("Warning {0}", e.Message)); 
     break; 
    } 
} 

Cuando se ejecuta el código anterior con los archivos XML y XSD definido anteriormente puedo obtener este resultado:

Validating... Error: The element 'MRIDSupportingData' in namespace 'urn:GenericLabData' has invalid child element 'MRIDNumber' in namespace 'urn:GenericLabData'. List of possible elements expected: 'MRIDNumber'. Finished Validating

¿Qué me falta? Por lo que puedo decir, MRIDNumber es MRIDNumber así que ¿por qué el error?

El archivo XML real es mucho más grande que XSD, pero falla al principio, así que reduje el problema a casi nada.

Cualquier ayuda sobre esto sería genial.

Gracias,
Keith


Por cierto, estos archivos de trabajo:

XML:

<?xml version='1.0'?> 
<bookstore xmlns="urn:bookstore-schema"> 
    <book genre="novel"> 
    <title>The Confidence Man</title> 
    <author> 
     <first-name>Herman</first-name> 
     <last-name>Melville</last-name> 
    </author> 
    <price>11.99</price> 
    </book> 
</bookstore> 

esquema:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns="urn:bookstore-schema" 
    elementFormDefault="qualified" 
    targetNamespace="urn:bookstore-schema"> 
    <xsd:element name="bookstore"> 
    <xsd:complexType> 
     <xsd:sequence > 
     <xsd:element name="book" maxOccurs="unbounded"> 
      <xsd:complexType> 
      <xsd:sequence > 
       <xsd:element name="title" type="xsd:string"/> 
       <xsd:element name="author"> 
       <xsd:complexType> 
        <xsd:sequence > 
        <xsd:element name="first-name" type="xsd:string"/> 
        <xsd:element name="last-name" type="xsd:string"/> 
        </xsd:sequence> 
       </xsd:complexType> 
       </xsd:element> 
       <xsd:element name="price" type="xsd:decimal"/> 
      </xsd:sequence> 
      <xsd:attribute name="genre" type="xsd:string"/> 
      </xsd:complexType> 
     </xsd:element> 
     </xsd:sequence>  
    </xsd:complexType> 
    </xsd:element> 
</xsd:schema> 

Respuesta

6

Pruebe agregar el atributo elementFormDefault="qualified" en el elemento xs:schema de su archivo XSD.

Creo que el validador dice que quiere un elemento MRIDNumber sin espacio de nombres, en lugar de su elemento MRIDNumber con el espacio de nombres urn:GenericLabData.

+0

Lo intenté y funciona .... Entonces, ¿por qué esto soluciona el problema? –

+0

Editado en mi respuesta: en la versión anterior de su XSD, el elemento MRIDNumber no estaba calificado (no pertenecía al espacio de nombres de destino/predeterminado).Consulte este enlace: http://www.xfront.com/DefaultNamespace.html –

+0

PD: si funciona, indique esta publicación como la respuesta a su pregunta para que otros usuarios puedan encontrarla cuando tengan el mismo problema ... –

1

En el pequeño extracto de XML/XSD que está probando actualmente, ¿incluyó PrescribedTestDate en el XSD también?

+0

No importa si PrescribedTestDate está en el archivo XML o no. El error es el mismo, deteniéndose en el elemento MRIDNumber. –

+0

No estoy seguro de por qué obtendría un error al hacer referencia a MRIDNumber si el problema es PrescribedTestDate, pero la diferencia que veo en su XML generado y el XML que funciona (así como el XSD) es que ni el XML que funciona ni el XSD contiene PrescribedTestDate. Me gustaría asegurarme de que está allí y ver si el error desaparece. – AllenG

+0

El problema no era el PrescribedTestDate. –

Cuestiones relacionadas