Problem validation a XML file with a local DTD file in C#
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
Jonathan
neverending student ;) https://es.linkedin.com/pub/jonathan-fernández-román/102/944/908
Updated on June 18, 2022Comments
-
Jonathan almost 2 years
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.
-
Jonathan over 14 yearsbut I want the user to select from the HD both files, the XML and the dtd, and tell him if the XML is valid or not. I'm pretty sure that it can be done, but I don't know how :(
-
Jonathan over 14 yearsI also tried ir before (and now again) with no luck. I obtain the same error. It's a little frustrating xD
-
Geoff over 14 yearsUpdated my aswer with a possible solution to load the DTD from a local file.
-
Zach Bonham over 14 years@Johnathan Maybe, after creating your XmlReader (in your original sample above), check the value of XmlReader.Settings.ProhibitDtd and see if it truly is false? From your question, I'm not sure if that was the value you were checking, or the value on the initial settings.ProhibitDtd. Just make sure they are showing the same value. If the reader does't, try setting it to false before loading your schemas? You've probably already tried it but there is nothing else that looks like it might even be an issue?
-
Jonathan over 14 yearsI will try it as soon as posible. Thanks.
-
fretje almost 14 years@Jonathan: Did you actually manage to get this to work with a .dtd file? I don't think XmlSchemaSet can be used with a .dtd file... Only .xsd files. I keep getting that error message, no matter what I try.
-
Jonathan almost 14 yearsI didn't try it again until now. We did a workarround. I tried it yesterday because you left a comment. No answers for months, so I accepted de more detailed question.
-
Concrete Gannet over 10 years-1. fretje is correct, XmlSchemaSet is intended for XMl schemas (XSD) only.