在C#中使用本地DTD文件validationXML文件的问题

我正在试图validationXML文件。 我正在使用此代码

XmlReaderSettings settings = new XmlReaderSettings(); settings.ProhibitDtd = false; settings.ValidationType = ValidationType.DTD; settings.ValidationEventHandler += new ValidationEventHandler(validationError); XmlSchemaSet schemas = new XmlSchemaSet(); settings.Schemas = schemas; XmlReader reader = XmlReader.Create(lblXmlPath.Text, settings); reader.Settings.Schemas.Add(null, lblDTDPath.Text); while (reader.Read()) { // empty by now } reader.Close(); 

但在行“reader.Settings.Schemas.Add(null,lblDTDPath.Text);” Visual Studio向我显示错误“出于安全原因,此XML文档中禁止使用DTD。要启用DTD处理,请将XmlReaderSettings上的ProhibitDtd属性设置为false并将设置传递给XmlReader.Create方法”

正如您在代码中看到的那样,ProhibitDtd被设置为false(我也在调试期间validation过)。 我还尝试在调用XmlReader.Create()之前添加Schema,但没有成功。

我之前做了一段时间来validationRSS提要。 通过本地存储的DTD进行validation的方法是将自定义XmlResolver插入XmlReader

 XmlReaderSettings readerSettings = new XmlReaderSettings(); readerSettings.ValidationType = ValidationType.DTD; readerSettings.ProhibitDtd = false; readerSettings.XmlResolver = new XmlFakeDtdResolver(); 

这将为读者提供本地DTD(对于已知格式),而不是从DOCTYPE中给出的URL下载它。

 class XmlFakeDtdResolver : XmlUrlResolver { public static Dictionary dtdMap = new Dictionary(); public static Dictionary uriMap = new Dictionary(); static XmlFakeDtdResolver() { Uri rss091uri = new Uri("http://fake.uri/rss091"); uriMap["-//Netscape Communications//DTD RSS 0.91//EN"] = rss091uri; uriMap["http://my.netscape.com/publish/formats/rss-0.91.dtd"] = rss091uri; dtdMap[rss091uri] = Encoding.ASCII.GetBytes(Resources.rss_0_91dtd); } public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) { if (dtdMap.ContainsKey(absoluteUri) && ofObjectToReturn == typeof(Stream)) { return new MemoryStream(dtdMap[absoluteUri]); } return base.GetEntity(absoluteUri, role, ofObjectToReturn); } public override Uri ResolveUri(Uri baseUri, string relativeUri) { if (uriMap.ContainsKey(relativeUri)) return uriMap[relativeUri]; return base.ResolveUri(baseUri, relativeUri); } } 

最后,我决定最后不使用DTDvalidation并通过XML模式进行validation,原因之一是许多供稿不包含DOCTYPE

在调用XmlReader.Create之前,尝试将DTD模式添加到模式集合。

 XmlReaderSettings settings = new XmlReaderSettings(); settings.ProhibitDtd = false; settings.ValidationType = ValidationType.DTD; settings.ValidationEventHandler += new ValidationEventHandler(validationError); XmlSchemaSet schemas = new XmlSchemaSet(); schemas.Add(null, lblDTDPath.Text); settings.Schemas = schemas; XmlReader reader = XmlReader.Create(lblXmlPath.Text, settings); while (reader.Read()) { // empty by now } reader.Close(); 

从我的探索可以让它工作的唯一方法是不将模式添加到XmlReader 。 xml文档中指定的DTD必须是有效的URL,并且XmlReader每次都会下载它。

如果你需要shema是本地的,你可以使用正则表达式将DTD的url更改为指向本地文件,这样看起来就像是

  

请注意文件:在url中。 在将它传递给XmlReader之前在内存中执行此操作,这样您就不必修改xml文件只是为了修改它是正确的。

我有类似的问题。 对我来说,答案是DTD不需要像XML文件指出的那样通过Schema连接,通过模式添加导致我的问题。