Обработка открытых внешних DTD в .Net через XmlResolver - PullRequest
0 голосов
/ 15 февраля 2010

мой XML ссылается на DTD следующим образом:

<! DOCTYPE article PUBLIC "- // ВЛАДЕЛЕЦ // ИМЯ // EN" "<a href="http://invalid/path/to.dtd" rel="nofollow noreferrer">http://invalid/path/to.dtd">

DTD недоступен по указанному URL, но я могу загрузить его на свой диск. Я пытался реализовать пользовательский XmlResolver для загрузки DTD, но он не работает. Мой пользовательский XmlResolver реализует GetEntity, и через отладчик я вижу следующие вызовы:

  1. Запрашиваемый URI - это загружаемый XML-документ. Я открываю поток для этого документа и возвращаю его. Это отлично работает.
  2. DTD запрашивается как URI формата "file: ///absolut/path/to.xml/-//OWNER//NAME//EN". Я использую регулярное выражение для проверки - //. *? //, который работает нормально, но выглядит не очень чистым для меня. Но если DTD самодостаточен, он работает.
  3. DTD ссылается на modules.ent. Это приводит к вызову GetEntity с URI: «file: ///absolut/path/to.xml/-//OWNER//NAME//modules.ent». Очевидно, теперь довольно странно восстанавливать интенсивность пути.

Любой намек, как правильно это реализовать? Я думаю, что публичные внешние DTD довольно распространены в издательском секторе, поэтому должно быть чистое решение!?

ура, Ахим

1 Ответ

1 голос
/ 16 февраля 2010

"file:///absolut/path/to.xml/-//OWNER//NAME//EN" - это объединение СИСТЕМЫ и ПУБЛИЧНЫХ идентификаторов. Как правило, вы хотите посмотреть на одно или другое, а не на оба, и, конечно, не на одну строку. Когда вы говорите «DTD запрашивается как URI формата», неясно, кто выполняет запрос. Похоже, что вызывающий код объединяет SYSTEM и PUBLIC.

Если у вас есть DTD в виде файла диска, и все, что вам нужно сделать, это сопоставить один URI с другим, вы можете переопределить ResolveUri() вместо полного GetEntity(). GetEntity() более полезно, если у вас есть ресурсы, недоступные в виде простых URI, например, Вы вычисляете содержимое ресурса во время выполнения, извлекаете его из базы данных, используете нестандартную схему URL и протокол, такой как svn: etc.

...