2008-09-22 41 views
5

Tôi có một số phương pháp WCF được sử dụng để truyền tải thông tin từ một ứng dụng máy chủ đến một lối vào trang web để sử dụng trong ràng buộc. Tôi đang gửi kết quả dưới dạng một XElement, đó là một gốc của một cây XML chứa dữ liệu mà tôi muốn ràng buộc.Cách tốt nhất để kiểm tra tính hợp lệ của XML từ một phương pháp?

Tôi muốn tạo một số thử nghiệm kiểm tra dữ liệu và đảm bảo dữ liệu đi qua như mong đợi.

Suy nghĩ hiện tại của tôi là: Mỗi phương thức trả về cây XElement đều có tệp lược đồ tương ứng (.XSD). Tệp này được bao gồm trong assembly có chứa các lớp WCF của tôi như là một tài nguyên nhúng.

Thử nghiệm gọi phương thức trên các phương pháp này và so sánh kết quả với các lược đồ được nhúng này.

Đây có phải là một ý tưởng hay không? Nếu không, tôi có thể sử dụng những cách nào khác để cung cấp "bảo đảm" loại XML mà một phương thức sẽ trả về?

Nếu có, làm cách nào để bạn xác thực XElement dựa vào lược đồ? Và làm thế nào tôi có thể lấy lược đồ đó từ assembly mà nó được nhúng vào?

Trả lời

11

Id nói xác thực xml bằng lược đồ xsd là một ý tưởng hay.
Cách xác thực XElement với giản đồ đã nạp: Như bạn thấy trong ví dụ này, bạn cần phải xác thực XDocument trước để điền vào "infoset sau khi xác nhận lược đồ sau" (Có thể có giải pháp để làm điều này mà không cần sử dụng phương pháp Validate trên XDocument nhưng Im vẫn chưa tìm thấy một):

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

Làm thế nào để đọc các lược đồ nhúng từ một hội đồng và thêm nó vào 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)); 
+0

element.GetSchemaInfo() trả về null. – Will

+0

Tôi không có phương thức Validate trên XDocument, đây là một phương thức extention từ đó namespace? –

+1

cho bất kỳ ai cũng đang tìm kiếm không gian tên: bằng System.Xml.Schema; –

4

Nếu bạn' lại thực hiện một số công việc nhẹ và XSD là quá mức cần thiết, hãy xem xét cũng có thể đánh mạnh dữ liệu XML của bạn. Ví dụ, tôi có một số lớp trong một dự án bắt nguồn từ XElement. Một là ExceptionXElement, một là HttpHeaderXElement, vv Trong đó, tôi kế thừa từ XElement và thêm các phương thức Parse và TryParse để lấy các chuỗi chứa dữ liệu XML để tạo một cá thể từ đó. Nếu TryParse() trả về false, chuỗi không phù hợp với dữ liệu XML mà tôi mong đợi (phần tử gốc có tên sai, thiếu các phần tử con, v.v.).

Ví dụ:

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... 
    } 
Các vấn đề liên quan