【问题标题】:How best to test the validity of XML from a method?如何最好地从方法中测试 XML 的有效性?
【发布时间】:2010-09-12 03:12:24
【问题描述】:

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

我想创建一些测试来检查数据并确保数据符合预期。

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

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

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

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

【问题讨论】:

    标签: c# .net xml unit-testing xsd


    【解决方案1】:

    我说使用 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));
    

    【讨论】:

    • element.GetSchemaInfo() 返回 null。
    • 我在 XDocument 上没有 Validate 方法,这是来自哪个命名空间的扩展方法?
    • 对于任何也在寻找名称空间的人:使用 System.Xml.Schema;
    【解决方案2】:

    如果您正在做一些轻量级的工作并且 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...
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-05
      相关资源
      最近更新 更多