Вопрос

В предыдущий вопрос Я упомянул некоторую работу со сторонней DLL, интерфейс которой использует ряд входных данных XML, определенных с помощью DTD.До сих пор все шло гладко, но у меня все еще есть неприятная проблема с разрешением объявления типа документа в сгенерированных входных значениях.

Чего я не могу понять, так это того, что является решающим фактором при определении того, где искать указанный файл DTD.Если у меня есть объявление, которое выглядит так:

<!DOCTYPE ElementName SYSTEM "ElementName.dtd">

Первоначально я думал, что текущий путь выполнения приложения — это место, где анализатор будет искать DTD.Однако, когда я пытаюсь использовать XML-элемент управления в ASP.Net ошибка, которую я получаю, сбивает меня с толку...

Не удалось найти File 'C: Program Files Microsoft Visual Studio 9.0 common7 ide elementName.dtd'

Почему он ищет там DTD?

Есть ли какие-нибудь гуру XML, которые могут мне помочь в этом вопросе.Я действительно не имею никакого контроля над XML, возвращаемым из этой DLL, так что мне делать?Есть ли способ «зарегистрировать» DTD в операционной системе?Нравится GAC?

Это было полезно?

Решение

К сожалению, библиотека, сгенерировавшая XML, использовала относительный URL-адрес для dtd, а не полный.Таким образом, XmlDocument XmlControl использует XmlResolver class для преобразования относительного пути в полный.По умолчанию он использует XmlUrlResolver (это конкретный XmlResolver).При этом будет предпринята попытка сопоставить расположение dtd с местоположением, которое, по его мнению, находится относительно документа Xml.Проблема в том, где находится XmlDocument?Вероятно, в памяти, которая не связана ни с чем, и XmlUrlResolver вместо этого использует местоположение процесса, которым в вашем случае является Visual Studio, которая находится по адресу «c:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe».

Так что ты можешь сделать?Ну, я полагаю, вам нужно создать собственный XmlResolver, который наследует от XmlUrlResolver, переопределяет метод ResolveUri и делает что-то подходящее.Сделав это, вам придется:

  1. Создайте класс XmlReaderSettings и задайте для свойства XmlReolver только что созданный класс.
  2. Создайте XmlReader, используя XmlReader.Create(), передав документ и объект XmlSettings.
  3. Создайте XmlDocument и вызовите передачу Load в XmlReader и, наконец.
  4. Установите для свойства XmlDocument вашего XmlControl значение XmlDocument.

Честно говоря, все это немного муторно, поэтому, если бы это было так, я бы просто использовал string.Replace, чтобы удалить объявление DTD из документа перед его обработкой в ​​XML.

Если вы действительно смелы, вы можете создать преобразователь, который наследуется непосредственно от XmlResolver.Как только вы это сделаете, вы можете переопределить GetEntity метод, а затем вы сможете получить документ dtd откуда угодно.Однажды я написал один, который получал dtds из файлов, встроенных в файлы ресурсов, но, к сожалению, у меня больше нет кода :-(

Другие советы

Если вас на самом деле не заботит проверка каждого документа на соответствие его DTD, вы можете установить для свойства XmlResolver значение null в вашем XmlTextReader (или XmlDocument), чтобы полностью игнорировать DTD.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top