如何在C#中使用DTD验证XML文档?

7
我不想做任何花哨的事情,我只想确保一个文档是有效的,并在无效时打印错误消息。谷歌指向了这个链接,但它似乎已经过时了(至少,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#”是什么意思?我的代码已经是C# 3.0了。 - Mehrdad Afshari
@Mehrdad:抱歉,我在学习C# 1.0时写的代码,当时不知道var在C#中是有效的。 - Matthew
4个回答

7

不要直接创建 XmlValidatingReader,而应该构造一个适当的XmlReaderSettings 对象并将其作为参数传递给XmlReader.Create 方法

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

其余部分不变。

P.S. OnValidationEvent 是你声明的用于处理验证事件的方法名称。显然,如果你不想订阅由XmlReader引发的验证事件,可以删除此行。


Matthew:这是你声明来处理验证失败事件的方法。如果你想让它抛出异常,你可以完全删除那行代码。 - Mehrdad Afshari

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表达式

类型推断


嗯,梅尔达德在你之前22分钟基本上给出了相同的答案,是吗? - Robert Harvey
这个答案是完成相同任务的另一种方式。 - ChaosPandion

0
我参考了DTD验证的这个示例。 https://learn.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>

-1

完整描述:

在Visual Studio .NET中,创建一个名为ValidateXml的新Visual C#控制台应用程序项目。在Class1.cs的开头添加两个using语句,如下所示:
using System.Xml;        // 用于XmlTextReader和XmlValidatingReader
using System.Xml.Schema; // 用于XmlSchemaCollection(稍后将使用)

Class1.cs中,在Main方法开始之前声明一个名为isValid的布尔变量,如下所示:
private static bool isValid = true;      // 如果发生验证错误,
                                         // 在验证事件处理程序中将此标志设置为false。

Main方法中创建一个XmlTextReader对象以从文本文件中读取XML文档,然后创建一个XmlValidatingReader来验证此XML数据,如下所示:
XmlTextReader r = new XmlTextReader("C:\\MyFolder\\ProductWithDTD.xml");
XmlValidatingReader v = new XmlValidatingReader(r);
XmlValidatingReader对象的ValidationType属性指示所需的验证类型(DTD、XDR或模式)。将此属性设置为DTD,如下所示:
v.ValidationType = ValidationType.DTD;

如果发生任何验证错误,则验证读取器会生成验证事件。添加以下代码以注册验证事件处理程序(您将在步骤7中实现MyValidationEventHandler方法):
v.ValidationEventHandler += 
   new ValidationEventHandler(MyValidationEventHandler);

添加以下代码以读取和验证XML文档。如果发生任何验证错误,则调用MyValidationEventHandler来处理错误。此方法将isValid设置为false(请参见步骤8)。您可以在验证后检查isValid的状态,以查看文档是有效还是无效。
while (v.Read())
{
   // 可以在此处添加代码来处理内容。
}
v.Close();

// 检查文档是有效还是无效。
if (isValid)
   Console.WriteLine("Document is valid");
else
   Console.WriteLine("Document is invalid");

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以使其无效(例如,删除<AuthorName>M soliman</AuthorName>元素)。 再次运行应用程序。您应该收到以下错误消息:
Validation event
Element 'Product' has invalid content. Expected 'ProductName'.
An error occurred at file:///C:/MyFolder/ProductWithDTD.xml(4, 5).
Document is invalid

2
这只是一份MSDN示例的复制粘贴,几乎是逐字逐句的。至少,请提供一个参考链接:http://support.microsoft.com/kb/307379 - Pure.Krome

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接