2008-09-22 12 views
5

Bir sunucu uygulamasından bir web sitesi önyüzüne, ciltlemede kullanılmak üzere bilgi iletmek için kullanılan bazı WCF yöntemleri kullanıyorum. Sonuca, bağlamak istediğim verileri içeren bir XML ağacının kökü olan XElement olarak gönderiyorum.XML'in geçerliliğini bir yöntemden en iyi nasıl test edebilirsiniz?

Verileri inceleyen ve beklendiği gibi karşılaştığından emin olmak için bazı testler oluşturmak istiyorum.

Şu anki düşüncem şudur: Bir XElement ağacı döndüren her yönteme karşılık gelen bir şema (.XSD) dosyası vardır. Bu dosya, WCF sınıflarımı gömülü bir kaynak olarak içeren derleme içinde yer almaktadır.

Testler, bu yöntemlerde yöntemi çağırır ve sonucu bu yerleşik şemalara göre karşılaştırır.

Bu iyi bir fikir mi? Değilse, bir yöntemin ne tür bir XML'e dönüşeceğine dair bir "garanti" sağlamak için başka hangi yolları kullanabilirim?

Eğer bir XElement'i şemaya karşı nasıl doğrularsınız? Ve bu şemayı gömülü montajdan nasıl alabilirim?

cevap

11

Bir xsd şemasıyla xml doğrulanıyor diyelim iyi bir fikir.

Yüklü şema ile XElement doğrulanır: Bu örnekte gördüğünüz gibi, önce "şema doğrulama sınaması" nı doldurmak için XDocument'i doğrulamanız gerekir (Bunu yapmak için bir çözüm olabilir) henüz) bulmak için XDocument ama Im Onaylat yöntemi kullanarak:

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

Nasıl bir derleme gömülü şema okuyup XmlSchemaSet eklemek için:

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

element.GetSchemaInfo() boş döner. – Will

+0

XDocument üzerinde Validate yöntemine sahip değilim, bu ad alanından hangi bir uzatma yöntemidir? Ayrıca, System.Xml.Schema kullanarak ad alanını arayan herkes için –

+1

: ; –

4

Eğer' tekrar hafif bir çalışma yapmak ve XSD'ler çok fazla uğraşıyor, ayrıca muhtemelen XML verilerinizi yazmayı da düşünün. Örneğin, bir projede XElement'den türeyen bir dizi sınıf var. Biri ExceptionXElement, diğeri HttpHeaderXElement, vb. Onlarda, XElement öğesinden miras alır ve bir örnek oluşturmak için XML verilerini içeren dizeleri alan Parse ve TryParse yöntemlerini eklerim. TryParse() öğesi false değerini döndürürse, dize beklediğim XML verisine uymaz (kök öğenin adı yanlıştır, alt öğe öğeleri eksiktir). Örneğin

:

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... 
    }