【问题标题】:How do I validate an XML document against a DTD in C#?如何在 C# 中根据 DTD 验证 XML 文档?
【发布时间】:2010-12-12 02:44:25
【问题描述】:

我不想做任何花哨的事情,我只想确保文档有效,如果不是则打印错误消息。 Google 将我指向 this,但似乎 XmlValidatingReader 已过时(至少 MonoDevelop 是这样告诉我的)。

编辑:我正在尝试 Mehrdad 的提示,但我遇到了麻烦。我想我已经掌握了大部分,但我在任何地方都找不到 OnValidationEvent。我从哪里得到 OnValidationEvent?

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.DTD;
settings.ValidationEventHandler += new ValidationEventHandler(/*trouble is here*/);
XmlReader validatingReader = XmlReader.Create(fileToLoad, settings);

【问题讨论】:

  • 顺便说一句,“转换为 C#”是什么意思。我的代码 is 在 C# 3.0 中。
  • @Mehrdad:抱歉,我在学习 C# 1.0 时写了这个,不知道 var 在 C# 中有效。

标签: c# xml validation dtd


【解决方案1】:

我在 DTD 验证中提到了这个示例。 https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlreadersettings.dtdprocessing?view=netcore-3.1#input

此示例包含无效的 DTD XML,我已将其更正如下。

<!--XML file using a DTD-->
<!DOCTYPE store [
  <!ELEMENT store (item)*> 
  <!ELEMENT item (name,dept,price)>
  <!ATTLIST item type CDATA #REQUIRED ISBN CDATA 
#REQUIRED>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT dept (#PCDATA)>
  <!ELEMENT price (#PCDATA)>]>
<store>
  <item type="supplies"  ISBN="2-3631-4">
    <name>paint</name>
    <dept>1</dept>
    <price>16.95</price>
  </item>
</store>

【讨论】:

    【解决方案2】:

    完整说明:

    1. 在 Visual Studio .NET 中,创建一个新的 Visual C# 控制台应用程序 名为ValidateXml 的项目。在开头添加两个 using 语句 Class1.cs 如下:

      using System.Xml;        // for XmlTextReader and XmlValidatingReader
      using System.Xml.Schema; // for XmlSchemaCollection (which is used later)
      
    2. Class1.cs 中,在前面声明一个名为isValid 的布尔变量 Main 方法的开头如下:

      private static bool isValid = true;      // If a validation error occurs,
                                               // set this flag to false in the
                                               // validation event handler. 
      
    3. 创建一个XmlTextReader 对象以从文本中读取 XML 文档 Main 方法中的文件,然后创建一个XmlValidatingReader 到 按如下方式验证此 XML 数据:

      XmlTextReader r = new XmlTextReader("C:\\MyFolder\\ProductWithDTD.xml");
      XmlValidatingReader v = new XmlValidatingReader(r);
      
    4. XmlValidatingReader 对象的ValidationType 属性 指示所需的验证类型(DTD、XDR 或 架构)。将此属性设置为 DTD,如下所示:

      v.ValidationType = ValidationType.DTD;
      
    5. 如果发生任何验证错误,验证阅读器会生成一个 验证事件。添加以下代码以注册验证 事件处理程序(您将实现 MyValidationEventHandler 步骤 7 中的方法):

      v.ValidationEventHandler += 
         new ValidationEventHandler(MyValidationEventHandler);
      
    6. 添加以下代码以读取和验证 XML 文档。如果有的话 发生验证错误,MyValidationEventHandler 被调用 解决错误。此方法将 isValid 设置为 false(参见步骤 8)。 验证后可以查看isValid的状态,看看是否 文件有效或无效。

      while (v.Read())
      {
         // Can add code here to process the content.
      }
      v.Close();
      
      // Check whether the document is valid or invalid.
      if (isValid)
         Console.WriteLine("Document is valid");
      else
         Console.WriteLine("Document is invalid");
      
    7. Main方法之后写MyValidationEventHandler方法为 如下:

      public static void MyValidationEventHandler(object sender, 
                                                  ValidationEventArgs args) 
      {
         isValid = false;
         Console.WriteLine("Validation event\n" + args.Message);
      }
      

    构建并运行应用程序。应用程序应该报告 XML 文档是有效的。 例如: 在 Visual Studio .NET 中,修改 ProductWithDTD.xml 以使其无效(例如,删除 &lt;AuthorName&gt;M soliman&lt;/AuthorName&gt; 元素)。 再次运行应用程序。您应该会收到以下错误消息:

    Validation event
    Element 'Product' has invalid content. Expected 'ProductName'.
    An error occurred at file:///C:/MyFolder/ProductWithDTD.xml(4, 5).
    Document is invalid
    

    【讨论】:

    【解决方案3】:
    var messages = new StringBuilder();
    var settings = new XmlReaderSettings { ValidationType = ValidationType.DTD };
    settings.ValidationEventHandler += (sender, args) => messages.AppendLine(args.Message);
    var reader = XmlReader.Create("file.xml", settings);
    
    if (messages.Length > 0)
    {
        // Log Validation Errors
        // Throw Exception
        // Etc.
    }
    

    ValidationEventHandler

    Lambda Expressions

    Type Inference

    【讨论】:

    • 嗯,Mehrdad 不是比你早 22 分钟给出了基本相同的答案吗?
    • 这个答案是完成同一件事的不同方式。
    【解决方案4】:

    您应该构造一个适当的XmlReaderSettings object 并将其作为参数传递给XmlReader.Create method,而不是直接创建XmlValidatingReader class

    var settings = new XmlReaderSettings { ValidationType = ValidationType.DTD };
    settings.ValidationEventHandler += new ValidationEventHandler(OnValidationEvent);
    var reader = XmlReader.Create("file.xml", settings);
    

    其余不变。

    附: OnValidationEvent 是您声明用于处理验证事件的方法的名称。显然,如果您不想订阅 XmlReader 引发的验证事件,则可以删除该行。

    【讨论】:

    • Matthew:这就是您声明的处理失败验证事件的方法。如果您希望它引发异常,则可以完全删除该行。
    猜你喜欢
    • 2019-10-25
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 2010-12-25
    • 2013-04-14
    • 2015-12-24
    相关资源
    最近更新 更多