Problem validation a XML file with a local DTD file in C#

只愿长相守 提交于 2019-12-09 13:03:05

问题


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();

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"

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.


回答1:


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();

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);
    }
}

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




回答2:


Try adding to your DTD schema to schemas collection before the call to XmlReader.Create.

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();



回答3:


From my poking around the only way i could get it to work is not to add the schema to the XmlReader. The DTD specified in the xml document must be a valid url and the XmlReader will download it each time.

If you need the shema to be local, you can change the url of the DTD to point to a local file using a regular expression so it would look somthing like

<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.3//EN" "file:C:\wml.dtd">

Note the file: in the url. Do this in memory before passing it to the XmlReader and that way you do not have to modify the xml file just to varify that it is correct.




回答4:


I had a similar problem. The answer, for me, was that the DTD doesn't need to be hooked up via the Schemas as the XML file points to out, adding via schemas caused me the issue.



来源:https://stackoverflow.com/questions/1508799/problem-validation-a-xml-file-with-a-local-dtd-file-in-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!