针对 XSD 的 XML 验证始终返回 true

本文关键字:返回 true 验证 XSD XML 针对 | 更新日期: 2023-09-27 18:31:10

我有一个 c# 脚本,用于根据 XSD 文档验证 XML 文档,如下所示:

    static bool IsValidXml(string xmlFilePath, string xsdFilePath)
    {
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.Schemas.Add(null, xsdFilePath);
        settings.ValidationType = ValidationType.Schema;
        settings.Schemas.Compile();
        try
        {
            XmlReader xmlRead = XmlReader.Create(xmlFilePath, settings);
            while (xmlRead.Read())
            { };
            xmlRead.Close();
        }
        catch (Exception e)
        {
            return false;
        }
        return true;
    }

在查看了许多 MSDN 文章和此处的问题后,我对此进行了编译,这是解决方案。它确实正确地验证了XSD的格式是否正确(如果我弄乱了文件,则返回false)并检查XML的格式是否正确(弄乱时也返回false)。

我也尝试了以下内容,但它做完全相同的事情:

    static bool IsValidXml(string xmlFilePath, string xsdFilePath)
    {
        XDocument xdoc = XDocument.Load(xmlFilePath);
        XmlSchemaSet schemas = new XmlSchemaSet();
        schemas.Add(null, xsdFilePath);
        try
        {
            xdoc.Validate(schemas, null);
        }
        catch (XmlSchemaValidationException e)
        {
            return false;
        }
        return true;
    }

我什至从互联网上提取了一个完全随机的 XSD 并将其放入两个脚本中,它仍然在两个脚本上都有效。我在这里错过了什么?

在 SSIS 作业中使用 .NET 3.5。

针对 XSD 的 XML 验证始终返回 true

在 .NET 中,您必须检查自己验证程序是否与架构组件实际匹配;如果不匹配,则不会引发异常,因此您的代码将无法按预期工作。

匹配是指以下一项或两项:

  • 架构集中有一个全局元素,其限定名与 XML 文档元素的限定名相同。
  • 文档元素具有 xsi:type 属性,该属性是指向架构集中的全局类型的限定名称。

在流模式下,您可以轻松进行此检查。这种伪代码应该给你一个想法(未显示错误处理等):

using (XmlReader reader = XmlReader.Create(xmlfile, settings))
{
    reader.MoveToContent();
    var qn = new XmlQualifiedName(reader.LocalName, reader.NamespaceURI);
    // element test: schemas.GlobalElements.ContainsKey(qn);
    // check if there's an xsi:type attribute: reader["type", XmlSchema.InstanceNamespace] != null;
    // if exists, resolve the value of the xsi:type attribute to an XmlQualifiedName
    // type test: schemas.GlobalTypes.ContainsKey(qn);
    // if all good, keep reading; otherwise, break here after setting your error flag, etc.
}

您还可以考虑 XmlNode.SchemaInfo,它表示作为架构验证的结果分配给节点的架构验证后信息集。我会测试不同的条件,看看它如何适用于你的场景。建议使用第一种方法来减少 DoS 攻击中的攻击面,因为它是检测完全虚假有效负载的最快方法。