2008-09-22 2 views
5

서버 응용 프로그램에서 바인딩에 사용할 웹 사이트 프론트 엔드로 정보를 전송하는 데 사용되는 일부 WCF 메서드가 있습니다. 내가 바인딩하려는 데이터가 포함 된 XML 트리의 루트 인 XElement로 결과를 보냅니다.메서드에서 XML의 유효성을 테스트하는 가장 좋은 방법은 무엇입니까?

데이터를 검사하고 예상대로 건너 오는지 확인하는 테스트를 만들고 싶습니다.

내 생각은 다음과 같습니다. XElement 트리를 반환하는 모든 메서드에는 해당 스키마 (.XSD) 파일이 있습니다. 이 파일은 내 WCF 클래스가 포함 된 리소스로 포함 된 어셈블리 내에 포함되어 있습니다.

테스트에서는 이러한 메서드에 대한 메서드를 호출하고 결과를 이러한 포함 된 스키마와 비교합니다.

이것은 좋은 아이디어입니까? 그렇지 않은 경우, 메소드가 리턴 할 XML의 종류에 대한 "보증"을 제공하기 위해 어떤 다른 f}을 사용할 수 있습니까?

그렇다면 스키마에 대해 XElement의 유효성을 어떻게 확인합니까? 그리고이 스키마를 임베디드 어셈블리에서 어떻게 가져올 수 있습니까?

답변

11

ID는 xsd 스키마로 xml을 확인하는 것이 좋습니다.

로드 된 스키마로 XElement의 유효성을 검사하는 방법 : 이 예에서 알 수 있듯이 XDocument의 유효성을 검사하여 "스키마 유효성 검사 후 정보 집합"을 채워야합니다. 아직) 하나를 찾을하여 XDocument하지만 임에 유효성 검사 방법을 사용하여 :

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

방법 어셈블리에서 포함 된 스키마를 읽고 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()는 null를 돌려줍니다. – Will

+0

XDocument에 대해 Validate 메서드가 없으므로이 메서드는 네임 스페이스의 확장 메서드입니까? 이름 공간을 찾고있는 사용자는 –

+1

입니다. using System.Xml.Schema; –

4

당신이 만약 ' 다시 약간의 가벼운 작업을하고 XSD가 과도 할 경우 XML 데이터를 강력하게 입력하는 것도 고려하십시오. 예를 들어, XElement에서 파생 된 프로젝트에 여러 클래스가 있습니다. 하나는 ExceptionXElement이고, 다른 하나는 HttpHeaderXElement입니다. 그 중 XElement에서 상속 받아 XML 데이터가 포함 된 문자열을 취하는 Parse 및 TryParse 메서드를 추가하여 인스턴스를 만듭니다. TryParse()가 false를 반환하면 문자열이 예상 한 XML 데이터를 따르지 않습니다 (루트 요소의 이름이 잘못되었거나 자식 요소가 누락 된 경우 등). 예를 들어

:

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... 
    } 
관련 문제