메소드에서 XML의 유효성을 테스트하는 가장 좋은 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/117007

문제

바인딩에 사용하기 위해 서버 응용 프로그램에서 웹 사이트 프런트 엔드로 정보를 전송하는 데 사용되는 몇 가지 WCF 메서드가 있습니다.바인딩하려는 데이터가 포함된 XML 트리의 루트인 XElement로 결과를 보냅니다.

데이터를 검사하고 예상대로 나타나는지 확인하는 몇 가지 테스트를 만들고 싶습니다.

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

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

이것이 좋은 생각입니까?그렇지 않은 경우 메서드가 어떤 종류의 XML을 반환할지에 대한 "보장"을 제공하기 위해 어떤 다른 방법을 사용할 수 있습니까?

그렇다면 스키마에 대해 XElement의 유효성을 어떻게 검사합니까?그리고 해당 스키마가 포함된 어셈블리에서 해당 스키마를 어떻게 얻을 수 있습니까?

도움이 되었습니까?

해결책

xsd 스키마로 xml의 유효성을 검사하는 것이 좋은 생각이라고 생각합니다.

로드된 스키마를 사용하여 XElement의 유효성을 검사하는 방법:이 예에서 볼 수 있듯이 "스키마 유효성 검사 후 정보 집합"을 채우기 위해 먼저 XDocument의 유효성을 검사해야 합니다(XDOcument에서 Validate 메서드를 사용하지 않고 이 작업을 수행하는 솔루션이 있을 수 있지만 아직 찾지 못했습니다).

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

다른 팁

가벼운 작업을 수행 중이고 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...
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top