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>
Lo intenté y funciona .... Entonces, ¿por qué esto soluciona el problema? –
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 –
PD: si funciona, indique esta publicación como la respuesta a su pregunta para que otros usuarios puedan encontrarla cuando tengan el mismo problema ... –