8

假设我有一个模式,我希望输入文档符合该模式。我根据这样的架构加载文件:

// Load the ABC XSD
var schemata = new XmlSchemaSet();
string abcSchema = FooResources.AbcTemplate;
using (var reader = new StringReader(abcSchema))
using (var schemaReader = XmlReader.Create(reader))
{
    schemata.Add(string.Empty, schemaReader);
}

// Load the ABC file itself
var settings = new XmlReaderSettings
{
    CheckCharacters = true,
    CloseInput = false,
    ConformanceLevel = ConformanceLevel.Document,
    IgnoreComments = true,
    Schemas = schemata,
    ValidationType = ValidationType.Schema,
    ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings
};

XDocument inputDoc;
try
{
    using (var docReader = XmlReader.Create(configurationFile, settings))
    {
        inputDoc = XDocument.Load(docReader);
    }
}
catch (XmlSchemaException xsdViolation)
{
    throw new InvalidDataException(".abc file format constraint violated.", xsdViolation);
}

这可以很好地检测文件中的琐碎错误。然而,因为模式被锁定到一个命名空间,像下面这样的文档是无效的,但会偷偷溜过去:

<badDoc xmlns="http://Foo/Bar/Bax">
  This is not a valid document; but Schema doesn't catch it
  because of that xmlns in the badDoc element.
</badDoc>

我想说只有我拥有架构的命名空间才能通过架构验证。

4

3 回答 3

2

尽管看起来很愚蠢,但您要查看的内容实际上是在XmlReaderSettings对象上:

settings.ValidationEventHandler += 
    (node, e) => Console.WriteLine("Bad node: {0}", node);
于 2013-02-26T20:52:13.507 回答
1

我最终确定的解决方案是基本上检查根节点是否在我期望的命名空间中。如果不是,那么我会像对待真正的模式验证失败一样对待它:

// Parse the bits we need out of that file
var rootNode = inputDoc.Root;
if (!rootNode.Name.NamespaceName.Equals(string.Empty, StringComparison.Ordinal))
{
    throw new InvalidDataException(".abc file format namespace did not match.");
}
于 2013-03-01T20:26:26.917 回答
-1

设置 ReportValidationWarnings 标志。请参阅http://msdn.microsoft.com/en-us/library/system.xml.schema.xmlschemavalidationflags.aspxhttp://msdn.microsoft.com/en-us/library/system.xml.xmlreadersettings.validationflags .aspx

于 2013-02-26T20:11:41.433 回答