2009-06-03 20 views
7

Me encuentro con dificultades reales para validar XML con XSD. Debo prefijar todo esto y declarar desde el principio, soy nuevo en XSD y validación, por lo que no estoy seguro de si se trata de un problema de código o XML. He estado en el infierno de XML API y de nuevo con las diferentes opciones y creo que he encontrado cuál sería la estrategia ideal para validar XML con XSD. Tenga en cuenta que mi XML y XSD provienen de una base de datos, por lo que no necesito leer nada del disco.Validar XML con XSD

Reduje mi problema a una simple aplicación de muestra Windows Forms. Tiene un cuadro de texto para XSD (txtXsd), un cuadro de texto para XML (txtXml), un cuadro de texto para el resultado (txtResult) y un botón para iniciar la validación (btnValidate).

estoy usando un archivo XSD de ejemplo de Microsoft,

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:bookstore-schema" elementFormDefault="qualified" targetNamespace="urn:bookstore-schema"> 
    <xsd:element name="title" type="xsd:string" /> 
    <xsd:element name="comment" type="xsd:string" /> 
    <xsd:element name="author" type="authorName"/> 
    <xsd:complexType name="authorName"> 
     <xsd:sequence> 
      <xsd:element name="first-name" type="xsd:string" /> 
      <xsd:element name="last-name" type="xsd:string" /> 
     </xsd:sequence> 
    </xsd:complexType> 
</xsd:schema> 

estoy usando el siguiente código en mi aplicación.

private void btnValidate_Click (object sender, EventArgs e) 
{ 
    try 
    { 
     XmlTextReader reader = new XmlTextReader(txtXsd.Text, XmlNodeType.Document, new XmlParserContext(null, null, String.Empty, XmlSpace.None)); 
     XmlSchema schema = XmlSchema.Read(reader, null); 
     XmlSchemaSet schemas = new XmlSchemaSet(); 
     schemas.Add(schema); 

     XDocument doc = XDocument.Parse(txtXml.Text); 
     doc.Validate(schemas, ValidateSchema); 
    } 
    catch (Exception exception) 
    { 
     txtResult.Text += exception.Message + Environment.NewLine; 
    } 
} 

private void ValidateSchema (Object sender, ValidationEventArgs e) 
{ 
    txtResult.Text += e.Message + Environment.NewLine; 
} 

Como prueba, puse en XML válido, pero lo que creo que no hay que conformarse con el XSD anteriormente.

<xml> 
    <bogusNode>blah</bogusNode> 
</xml> 

El resultado es nada, sin errores de validación de ningún tipo. ¿Cómo lo arreglo?

Respuesta

4

Bueno, para uno: su XSD define un espacio de nombres XML xmlns="urn:bookstore-schema" que no está presente en su archivo de prueba XML; por lo tanto, no se validará nada en su archivo de prueba XML.

Si elimina esos elementos forman el esquema:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
     <xsd:element name="title" type="xsd:string" /> 

entonces se valida correctamente el archivo XML de prueba y se quejan de los elementos equivocados.

También usar un elemento llamado <xml> podría no ser una buena idea, ya que la directiva <?xml ......?> es una directiva predefinida y no debe aparecer como nombre de etiqueta en ningún otro lugar de su documento.

Marc

+0

Tenía una sospecha furtiva de que eso era lo que estaba pasando. Ir a recoger un libro xml. –

+1

En la imagen más grande, estoy tratando de asegurarme de que xml enviado se ajuste a la xsd. ¿Hay alguna manera de validar si no están en el mismo espacio de nombres? ¿Debo hacer eso en código mirando ambos espacios de nombres? –

+0

Joshua: el XML que está validando debe ser del mismo espacio (s) de nombres que define el XSD. Ese es el objetivo de los espacios de nombres XML: poder mantener los identificadores/etiquetas que generalmente se usan (como '

') aparte, colocándolos en su propio espacio de nombres (como un espacio de nombres .NET). –

1

También puede probar XmlValidatingReader para la validación XML

+2

Por lo que yo sé, el XmlValidatingReader está en desuso con .NET 2.0 y ya no se debe usar. MSDN dice: "La clase XmlValidatingReader es obsoleta en Microsoft .NET Framework versión 2.0. Puede crear una instancia XmlReader de validación utilizando la clase XmlReaderSettings y el método Create. Para obtener más información, vea Validar datos XML con XmlReader." –

2

no quiero al usuario enviar XML que no está definido en el XSD.

¿Por qué te importa? Su esquema valida los nodos XML que están en su espacio de nombres. Su lógica de procesamiento procesa los nodos XML que están en su espacio de nombres. Los nodos que no están en su espacio de nombres no son relevantes ni para su esquema ni para su lógica.

Si es realmente esencial restringir todos los nodos en el documento XML a un espacio de nombre específico, puede lograrlo ampliando la lógica de validación básica XmlReader que se encontró .

public static void Main() 
    { 
     const string myNamespaceURN = "urn:my-namespace"; 

     XmlSchemaSet sc = new XmlSchemaSet(); 
     sc.Add(myNamespaceURN, "mySchema.xsd"); 

     XmlReaderSettings settings = new XmlReaderSettings(); 
     settings.ValidationType = ValidationType.Schema; 
     settings.Schemas = sc; 
     settings.ValidationEventHandler += ValidationCallBack; 

     XmlReader reader = XmlReader.Create("myDocument.xml", settings); 

     while (reader.Read()) 
     { 
      if ((reader.NodeType == XmlNodeType.Element || 
       reader.NodeType == XmlNodeType.Attribute) 
       && 
       reader.NamespaceURI != myNamespaceURN) 
      { 
       LogError(reader.NamespaceURI + " is not a valid namespace."); 
      } 
     } 
    } 

    private static void ValidationCallBack(object sender, ValidationEventArgs e) 
    { 
     LogError(e.Message); 
    } 

    private static void LogError(string msg) 
    { 
     Console.WriteLine(msg); 
    } 
+0

El enlace está muerto – Jowen