4

具有带命名空间的 XML 模式http://mynamespace。如果验证了具有默认命名空间的错误 XML 文档,xmlns="http://mynamespace"则会按预期抛出异常。而如果有人更改了 namespace( http://Wrongnamespace),这个错误的 XML 将通过验证

这是带有模式验证的单元测试。方法XSD_NotValid_2不能正常工作:

[TestClass]
public class XSDTest
{
    public System.Xml.XmlReaderSettings ReaderSettings
    {
        get
        {
            string sXSD = "<xsd:schema targetNamespace=\"http://mynamespace\" xmlns=\"http://mynamespace\""
                + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\">"
            + "<xsd:element name=\"Root\">"
            + "<xsd:complexType>"
                + "<xsd:sequence>"
                    + "<xsd:element name=\"Child\" minOccurs=\"1\" maxOccurs=\"1\" />"
                + "</xsd:sequence>"
             + "</xsd:complexType>"
            + "</xsd:element>"
            + "</xsd:schema>";

            System.Xml.Schema.XmlSchema schema = System.Xml.Schema.XmlSchema.Read(new System.IO.StringReader(sXSD)
                        , new System.Xml.Schema.ValidationEventHandler(OnValidationFail));

            System.Xml.XmlReaderSettings readerSettings_Ret = new System.Xml.XmlReaderSettings();
            readerSettings_Ret.ValidationType = System.Xml.ValidationType.Schema;
            readerSettings_Ret.ValidationEventHandler += new System.Xml.Schema.ValidationEventHandler(OnValidationFail);
            readerSettings_Ret.Schemas.Add(schema);

            return readerSettings_Ret;
        }
    }


    private void OnValidationFail(object s, System.Xml.Schema.ValidationEventArgs e)
    {
        throw new OperationCanceledException("Validation error: " + e.Message);
    }

    [TestMethod]
    public void XSD_Valid_Test()
    {
         // Valid elements and valid namespace
        String sXML_Valid = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
            + "<Root xmlns=\"http://mynamespace\"><Child /></Root>";
        System.Xml.XmlReader xmlReader_Valid = 
            System.Xml.XmlReader.Create(new System.IO.StringReader(sXML_Valid), this.ReaderSettings);
        while (xmlReader_Valid.Read()) { } // no fail expected
    }

    [TestMethod]
    [ExpectedException(typeof(OperationCanceledException))]
    public void XSD_NotValid_1()
    {
         // No valid elements, while valid namespace
        String sXML_NotValid_1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
            + "<BadRoot xmlns=\"http://mynamespace\"><Child /></BadRoot>";
        System.Xml.XmlReader xmlReader_NoValid_1 = 
            System.Xml.XmlReader.Create(new System.IO.StringReader(sXML_NotValid_1), this.ReaderSettings);
        while (xmlReader_NoValid_1.Read()) ;
    }

    [TestMethod]
    [ExpectedException(typeof(OperationCanceledException))]
    public void XSD_NotValid_2()
    {
        // No valid elements and no valid namespace
        String sXML_NotValid_2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
            + "<Root xmlns=\"http://Wrongnamespace\"><NotValidChild /></Root>";
        System.Xml.XmlReader xmlReader_NoValid_2 = 
            System.Xml.XmlReader.Create(new System.IO.StringReader(sXML_NotValid_2), this.ReaderSettings);
        while (xmlReader_NoValid_2.Read()) ;
    }
}

这是正常行为吗?如何强制正确的命名空间定位?Root以及在 XSD 有附加元素的情况下如何强制要求Root2元素?

4

1 回答 1

3

如果启用架构验证警告,您将收到以下错误:

找不到元素“http://Wrongnamespace:Root”的架构信息。

利用

readerSettings_Ret.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings;

几件小事:

  1. 即使在单元测试中,也不应该通过字符串操作来创建 XML。始终使用 XML API 创建 XML,因为他们知道“所有规则”。
  2. 即使在单元测试中,您也应该将实现 IDisposable 的对象的创建放在using块中。事实上,我想说的是,特别是在单元测试中,每个测试都应该独立于其他测试,你要确保在开始下一个测试之前已经清理了一个测试。
于 2012-08-13T13:54:43.993 回答