使用C#中的本地DTD文件验证XML文件时出现问题 [英] Problem validation a XML file with a local DTD file in C#

查看:187
本文介绍了使用C#中的本地DTD文件验证XML文件时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试验证XML文件。我正在使用此代码

I'm triying to validate a XML file. I'm using this code

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方法中。

But in the line "reader.Settings.Schemas.Add(null, lblDTDPath.Text);" Visual Studio show me that error "For security reasons DTD is prohibited in this XML document. To enable DTD processing set the ProhibitDtd property on XmlReaderSettings to false and pass the settings into XmlReader.Create method"

您可以在代码中看到,ProhibitDtd设置为false(我也在调试期间进行了验证)。我还试图在调用XmlReader.Create()之前添加模式,但没有成功。

As you can see in the code, ProhibitDtd is setted to false (I verified during debug too). I also tried to add the Schema before call to XmlReader.Create() with no success.

推荐答案

用于验证RSS feed。通过本地存储的DTD进行验证的方法是将自定义 XmlResolver 插入到 XmlReader

I did this some time before for validating RSS feeds. The method to do validation by locally stored DTD was to insert a custom XmlResolver to the XmlReader

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

这将为读者提供本地DTD(用于已知格式),而不是从给定的URL下载

which would give the reader the local DTD (for known formats) instead of downloading it from the URL given in DOCTYPE.

class XmlFakeDtdResolver : XmlUrlResolver
{
    public static Dictionary<Uri, byte[]> dtdMap = new Dictionary<Uri, byte[]>();
    public static Dictionary<string, Uri> uriMap = new Dictionary<string, Uri>();
    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);
    }
}

最后,我决定不使用DTD最后进行验证,然后通过XML模式进行验证,原因之一是许多提要中没有DOCTYPE

As an end note, I decided to not use DTD validation in the end and go for validation by XML schema, one reason being that many feeds didn't include the DOCTYPE

这篇关于使用C#中的本地DTD文件验证XML文件时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆