Ignore DOCTYPE .dtd, but .dtd file must still exist
Asked Answered
S

1

6

I have a web service that processes an HTTP request. The document it receives has an embeded DOCTYPE that specifies a .dtd file. I wish to use a newer XML schema validation file made for when newer devices connect to my service.

I can successfully ignore the validation that goes on in the .dtd file, but the .dtd file must exist on my local hard drive. I want to remove these obsolete files, and have not found a way.

Sample XML document I am processing:

<?xml version="1.0" encoding="us-ascii" standalone="no"?>
<!DOCTYPE SomeMessage SYSTEM "SomeMessage.dtd">
<SomeMessage>data</SomeMessage>

The function that I am using to open the document:

private void LoadXmlDoc(XmlTextReader myXmlTextReader)
{
    XmlReaderSettings readerSettings = new XmlReaderSettings();
    readerSettings.ValidationType = ValidationType.Schema;
    readerSettings.Schemas.Add(null, MyGoodSchemaFile);
    readerSettings.DtdProcessing = DtdProcessing.Ignore;
    readerSettings.XmlResolver = null; // Added as a test.

    readerSettings.ValidationEventHandler += ValidationEventHandle;
    XmlReader myXmlReader = XmlReader.Create(myXmlTextReader, readerSettings);

    XmlDocument myXmlDocument = new XmlDocument();
    myXmlDocument.XmlResolver = null; // Added as a test.
    myXmlDocument.Load(myXmlReader); // Exception thrown here!
}

The exception that is caught:

System.IO.FileNotFoundException: Could not find file 'c:\windows\system32\inetsrv\SomeMessage.dtd'.
File name: 'c:\windows\system32\inetsrv\SomeMessage.dtd'
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)

The content of the SomeMessage.dtd file is not used--it is ignored as I desire. However, the dummy file "c:\windows\system32\inetsrv\SomeMessage.dtd" must exist, otherwise the exception is thrown.

I am running on Windows 7, using Visual Studio 2010 and .Net 4.0

How can I ignore the embeded .dtd and also not require a dummy .dtd file to be installed on my computer?

Seagirt answered 8/10, 2010 at 21:9 Comment(2)
What kind of web service is this? Home grown or an ASP.NET Web Service (.asmx)? Is it the web service client that is looking for the DTD?Marvelmarvella
It is an .aspx service, with a .aspx.cs C# file. I don't think that matters, however. I think that any XML document that is read by the code snippet above which has a DOCTYPE with .dtd line will have the error no matter where you execute it.Seagirt
S
10

The solution is to set the underlying XmlTextReader's XmlResolver to null. Changing the XmlReaderSettings.XmlResolver=null did not help, nor did setting the XmlDocument.XmlResolver=null

Here is the corrected function:

private void LoadXmlDoc(XmlTextReader myXmlTextReader)
{
    // The next line is the fix!!!
    myXmlTextReader.XmlResolver = null;  // Don't require file in system32\inetsrv

    XmlReaderSettings readerSettings = new XmlReaderSettings();
    readerSettings.ValidationType = ValidationType.Schema;
    readerSettings.Schemas.Add(null, MyGoodSchemaFile);
    readerSettings.DtdProcessing = DtdProcessing.Ignore;
    readerSettings.XmlResolver = null; // Doesn't help

    readerSettings.ValidationEventHandler += ValidationEventHandle;
    XmlReader myXmlReader = XmlReader.Create(myXmlTextReader, readerSettings);

    XmlDocument myXmlDocument = new XmlDocument();
    myXmlDocument.XmlResolver = null; // Doesn't help
    myXmlDocument.Load(myXmlReader); // Load doc, no .dtd required on local disk
}
Seagirt answered 11/10, 2010 at 17:29 Comment(1)
You saved my life! I developed a dll that is working perfectly in formbased. But after attaching it to a .NET web app, it was crashing on the dtd. So this is only needed when using in web apps. Thanks!Hacker

© 2022 - 2024 — McMap. All rights reserved.