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

时间:2016-01-20 21:38:16

标签: c# xml validation xsd

我有一个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。

1 个答案:

答案 0 :(得分:0)

在.NET中,您必须检查验证器是否实际匹配架构组件;如果它没有,则不会抛出任何异常,因此您的代码将无法按预期工作。

匹配表示以下一项或两项:

  • 架构集中有一个全局元素,其限定名称与XML文档元素的限定名称相同。
  • document元素具有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攻击中的攻击面,因为它是检测完全伪造有效载荷的最快方法。