Pregunta

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

Me gustaría crear algunas pruebas que examinen los datos y garanticen que sean los esperados.

Mi pensamiento actual es este:Cada método que devuelve un árbol XElement tiene un archivo de esquema correspondiente (.XSD).Este archivo se incluye dentro del ensamblado que contiene mis clases WCF como un recurso integrado.

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

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

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

¿Fue útil?

Solución

Diría que validar xml con un esquema xsd es una buena idea.

Cómo validar un XElement con el esquema cargado:Como puede ver en este ejemplo, primero debe validar el XDocument para completar el "conjunto de información posterior a la validación del esquema" (puede haber una solución para hacer esto sin usar el método Validar en el XDOcument, pero todavía no he encontrado una):

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));

Otros consejos

Si está haciendo un trabajo liviano y los XSD son excesivos, considere también escribir 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 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, faltan elementos secundarios, 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...
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top