validator validate validar error con check c# .net xml unit-testing xsd

c# - validate - ¿Cuál es la mejor manera de probar la validez de XML a partir de un método?



validation xsd xml (2)

Tengo algunos métodos WCF que se utilizan para transmitir información desde una aplicación de servidor a una interfaz de sitio web para su uso en enlace. Estoy enviando el resultado como un XElement que es una raíz de un árbol XML que contiene los datos que quiero vincular.

Me gustaría crear algunas pruebas que examinen los datos y se aseguren de que funcionen como se esperaba.

Mi pensamiento actual es este: cada método que devuelve un árbol XElement tiene un archivo de esquema correspondiente (.XSD). Este archivo está incluido dentro del ensamblaje que contiene mis clases WCF como un recurso incrustado.

Las pruebas llaman al método en estos métodos y compara el resultado con estos esquemas incrustados.

¿Es esta una buena idea? Si no, ¿de qué otras maneras puedo usar para proporcionar una "garantía" de qué tipo de XML devolverá un método?

Si es así, ¿cómo se valida un XElement contra un esquema? ¿Y cómo puedo obtener ese esquema del ensamblaje en el que está incrustado?


Id decir validar xml con un esquema xsd es una buena idea.

Cómo validar un elemento XElement con el esquema cargado: como ve en este ejemplo, primero debe validar el XDocument para llenar el "infoset de validación posterior al esquema" (Puede haber una solución para hacerlo sin usar el método Validate en el XDOcument pero aún no he encontrado ninguno):

String xsd = @"<xsd:schema xmlns:xsd=''http://www.w3.org/2001/XMLSchema''> <xsd:element name=''root''> <xsd:complexType> <xsd:sequence> <xsd:element name=''child1'' minOccurs=''1'' maxOccurs=''1''> <xsd:complexType> <xsd:sequence> <xsd:element name=''grandchild1'' minOccurs=''1'' maxOccurs=''1''/> <xsd:element name=''grandchild2'' minOccurs=''1'' maxOccurs=''2''/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>"; String xml = @"<?xml version=''1.0''?> <root> <child1> <grandchild1>alpha</grandchild1> <grandchild2>beta</grandchild2> </child1> </root>"; XmlSchemaSet schemas = new XmlSchemaSet(); schemas.Add("", XmlReader.Create(new StringReader(xsd))); XDocument doc = XDocument.Load(XmlReader.Create(new StringReader(xml))); Boolean errors = false; doc.Validate(schemas, (sender, e) => { Console.WriteLine(e.Message); errors = true; }, true); errors = false; XElement child = doc.Element("root").Element("child1"); child.Validate(child.GetSchemaInfo().SchemaElement, schemas, (sender, e) => { Console.WriteLine(e.Message); errors = true; });

Cómo leer el esquema incrustado de un ensamblado y agregarlo al XmlSchemaSet:

Assembly assembly = Assembly.GetExecutingAssembly(); // you can use reflector to get the full namespace of your embedded resource here Stream stream = assembly.GetManifestResourceStream("AssemblyRootNamespace.Resources.XMLSchema.xsd"); XmlSchemaSet schemas = new XmlSchemaSet(); schemas.Add(null, XmlReader.Create(stream));


Si está haciendo un trabajo liviano y los XSD son excesivos, considere también posiblemente tipear fuertemente sus datos XML. Por ejemplo, tengo varias clases en un proyecto que se derivan de XElement. Uno es ExceptionXElement, otro es HttpHeaderXElement, etc. En ellos, heredo de XElement y agrego los métodos Parse y TryParse que toman cadenas que contienen datos XML para crear una instancia. Si TryParse () devuelve falso, la cadena no se ajusta a los datos XML que espero (el elemento raíz tiene el nombre incorrecto, elementos secundarios faltantes, etc.).

Por ejemplo:

public class MyXElement : XElement { public MyXElement(XElement element) : base(element) { } public static bool TryParse(string xml, out MyXElement myElement) { XElement xmlAsXElement; try { xmlAsXElement = XElement.Parse(xml); } catch (XmlException) { myElement = null; return false; } // Use LINQ to check if xmlAsElement has correct nodes... }