5

バインディングで使用するためにサーバーアプリケーションからWebサイトフロントエンドに情報を送信するために使用されるいくつかのWCFメソッドがあります。バインドするデータを含むXMLツリーのルートであるXElementとして結果を送信しています。

データを調べて、期待どおりにデータが検出されることを確認するテストをいくつか作成したいと思います。

私の現在の考えは次のとおりです。XElementツリーを返すすべてのメソッドには、対応するスキーマ(.XSD)ファイルがあります。このファイルは、埋め込みリソースとしてWCFクラスを含むアセンブリに含まれています。

テストはこれらのメソッドでメソッドを呼び出し、結果をこれらの埋め込みスキーマと比較します。

これは良い考えですか?そうでない場合、メソッドが返すXMLの種類の「保証」を提供するために他にどのような方法を使用できますか?

そうである場合、スキーマに対してXElementをどのように検証しますか?そして、それが埋め込まれているアセンブリからそのスキーマを取得するにはどうすればよいですか?

4

2 に答える 2

11

xsdスキーマでxmlを検証するのは良い考えだと思います。

ロードされたスキーマでXElementを検証する方法:この例でわかるように、最初にXDocumentを検証して、「post-schema-validationinfoset」にデータを入力する必要があります(Validateメソッドを使用せずにこれを行う解決策がある可能性があります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));
于 2008-09-22T20:02:58.807 に答える
4

軽量の作業を行っていて、XSD が過剰である場合は、XML データを厳密に型指定することも検討してください。たとえば、XElement から派生するプロジェクトに多数のクラスがあります。1 つは ExceptionXElement、もう 1 つは 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...
    }
于 2008-09-23T11:50:46.577 に答える