我有一个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。
答案 0 :(得分:0)
在.NET中,您必须检查验证器是否实际匹配架构组件;如果它没有,则不会抛出任何异常,因此您的代码将无法按预期工作。
匹配表示以下一项或两项:
在流媒体模式下,您可以轻松完成此项检查。这种伪代码类型应该给你一个想法(错误处理未显示等):
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攻击中的攻击面,因为它是检测完全伪造有效载荷的最快方法。