【问题标题】:XDocument.Validate is always successfulXDocument.Validate 总是成功的
【发布时间】:2013-06-21 10:05:53
【问题描述】:

我有一个未定义任何目标命名空间的架构文件,即它的定义如下所示:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <!--Elements, attributes, etc. -->
</xs:schema>

对应的 XML 如下所示:

<Documents p1:CRC="0" p1:Date="1900-01-01T01:01:01+01:00" p1:Name="Test" p1:Status="new" xmlns:p1="http://www.tempuri.org/pdms.xsd" xmlns="http://www.tempuri.org/pdms.xsd">
  <p1:Document p1:Date="2010-12-23T07:59:45" p1:ErrorCode="0" p1:ErrorMessage="" p1:Number="TEST00001" p1:Status="new"/>
</Documents>

根据架构验证此 XML,例如Altova XMLSpy 或 Oxygen XML 编辑器失败。

但是我在 C# (.NET 4.0) 中的验证并没有失败。 XML 被处理为XDocument 对象。如果我理解正确,那么XDocument.Validate() 会在架构中找不到命名空间时进行宽松的验证。因此验证不会失败。但是,我怎样才能对XDocument 实施“严格”验证?

这就是我尝试验证 XML 的方式:

public static void ValidateXml(XDocument xml, string xsdFilename) {
  XmlReaderSettings settings = new XmlReaderSettings();
  XmlSchemaSet schemaSet = new XmlSchemaSet();

  schemaSet.Add(string.empty, xsdFilename);
  settings.ValidationType = ValidationType.Schema;
  settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
  settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallback);

  xml.Validate(schemaSet, ValidationCallback);
}

private static void ValidationCallback(object sender, ValidationEventArgs args) {
  if (args.Severity == XmlSeverityType.Warning) {
    // Do warning stuff...
  } else if (args.Severity == XmlSeverityType.Error) {
    // Do error stuff...
  }
}

【问题讨论】:

  • 如何调用 Validate 方法?你处理 ValidationEventHandler 吗?
  • @Jehof 我已经用示例代码更新了我的问题。
  • 你用XmlReaderSettings做什么?
  • 好的,只是看到这行不通,对吧? settings 未使用。 XDocument 有可能吗?

标签: c# linq-to-xml


【解决方案1】:

我不确定是否可以使用 Validate 方法;如果您在 XDocument 上使用验证 XmlReader,其中 ValidationFlags 设置为发出验证警告,如

        XDocument doc = XDocument.Load("../../XMLFile1.xml");

        XmlSchemaSet schemaSet = new XmlSchemaSet();
        schemaSet.Add(null, "../../XMLSchema1.xsd");

        XmlReaderSettings xrs = new XmlReaderSettings();
        xrs.ValidationType = ValidationType.Schema;
        xrs.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
        xrs.Schemas = schemaSet;
        xrs.ValidationEventHandler += (o, s) => {
            Console.WriteLine("{0}: {1}", s.Severity, s.Message);
        };

        using (XmlReader xr = XmlReader.Create(doc.CreateReader(), xrs))
        {
            while (xr.Read()) { }
        }

那么 ValidationEventHandler 会为每个没有找到架构信息的节点发出警告。因此,您的 ValidationEventHandler 可以检查此类警告。但您不妨在调用 Validate 方法之前简单地将 doc.Root.Name.Namespace 与您拥有的架构的目标命名空间进行比较。

【讨论】:

    猜你喜欢
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 2013-03-12
    相关资源
    最近更新 更多