Domanda

Ho alcuni metodi WCF che vengono utilizzati per trasmettere informazioni da un'applicazione server a un frontend di siti Web da utilizzare in associazione. Sto inviando il risultato come XElement che è una radice di un albero XML contenente i dati a cui voglio legare.

Vorrei creare alcuni test che esaminano i dati e assicurano che vengano rilevati come previsto.

Il mio pensiero attuale è questo: ogni metodo che restituisce un albero XElement ha un file di schema (.XSD) corrispondente. Questo file è incluso nell'assembly che contiene le mie classi WCF come risorsa incorporata.

I test chiamano il metodo su questi metodi e confrontano il risultato con questi schemi incorporati.

È una buona idea? In caso contrario, quali altri modi posso utilizzare per fornire una "garanzia" di che tipo di XML restituirà un metodo?

In tal caso, come si convalida un XElement rispetto a uno schema? E come posso ottenere quello schema dall'assembly in cui è incorporato?

È stato utile?

Soluzione

ID dire che convalidare xml con uno schema xsd è una buona idea.

Come convalidare un XElement con lo schema caricato: Come vedi in questo esempio, devi prima convalidare XDocument per ottenere il popolamento " infoset di post-schema-validazione " (Potrebbe esserci una soluzione per farlo senza utilizzare il metodo Convalida su XDOcument ma non sono ancora riuscito a trovarne uno):

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

Come leggere lo schema incorporato da un assembly e aggiungerlo a 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));

Altri suggerimenti

Se stai facendo un po 'di lavoro leggero e gli XSD sono eccessivi, considera anche la possibilità di digitare fortemente i tuoi dati XML. Ad esempio, ho un numero di classi in un progetto che derivano da XElement. Uno è ExceptionXElement, un altro è HttpHeaderXElement, ecc. In essi eredito da XElement e aggiungo metodi Parse e TryParse che accettano stringhe contenenti dati XML da cui creare un'istanza. Se TryParse () restituisce false, la stringa non è conforme ai dati XML previsti (l'elemento radice ha un nome errato, elementi figlio mancanti, ecc.).

Ad esempio:

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...
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top