5

我有一些 WCF 方法用于将信息从服务器应用程序传输到网站前端以用于绑定。我将结果作为 XElement 发送,它是包含我要绑定的数据的 XML 树的根。

我想创建一些测试来检查数据并确保它按预期进行。

我目前的想法是:每个返回 XElement 树的方法都有一个对应的模式 (.XSD) 文件。此文件包含在包含我的 WCF 类作为嵌入资源的程序集中。

测试在这些方法上调用方法,并将结果与​​这些嵌入式模式进行比较。

这是一个好主意吗?如果不是,我可以使用哪些其他方式来提供方法将返回哪种 XML 的“保证”?

如果是,您如何根据模式验证 XElement?以及如何从它嵌入的程序集中获取该架构?

4

2 回答 2

11

我说用 xsd 模式验证 xml 是个好主意。

如何使用加载的模式验证 XElement:正如您在此示例中看到的,您需要首先验证 XDocument 以填充“后模式验证信息集”(可能有一个解决方案可以在不使用 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 派生的类。一个是 ExceptionXElement,另一个是 HttpHeaderXElement 等。在它们中,我从 XElement 继承并添加 Parse 和 TryParse 方法,这些方法采用包含 XML 数据的字符串来创建实例。如果 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 回答