При использовании XmlDocument.Load я нахожу, что если документ относится к DTD, выполняется соединение с предоставленным URI. Есть ли способ предотвратить это?
После некоторого дополнительного копания, возможно, вы должны установить для свойства XmlResolver объекта XmlReaderSettings значение null.
«XmlResolver используется для поиска и открытия документа экземпляра XML или для поиска и открытия любых внешних ресурсов, на которые ссылается документ экземпляра XML. Сюда могут входить объекты, DTD или схемы. ‘
Таким образом, код будет выглядеть так:
XmlReaderSettings settings = new XmlReaderSettings(); settings.XmlResolver = null; settings.DtdProcessing = DtdProcessing.Parse; XmlDocument doc = new XmlDocument(); using (StringReader sr = new StringReader(xml)) using (XmlReader reader = XmlReader.Create(sr, settings)) { doc.Load(reader); }
Загружаемый документ имеет DTD.
С:
settings.ProhibitDtd = true;
Я вижу следующее исключение:
Служба не может быть запущена. System.Xml.XmlException: по соображениям безопасности DTD запрещен в этом документе XML. Чтобы включить обработку DTD, установите для свойства ProhibitDtd значение XmlReaderSettings значение false и передайте настройки в метод XmlReader.Create.
Итак, похоже, что ProhibitDtd ДОЛЖЕН быть установлен в true в этом случае.
Похоже, что ValidationType будет делать трюк, но с:
settings.ValidationType = ValidationType.None;
Я все еще вижу связь с DTD uri.
На самом деле это недостаток в спецификациях XML. W3C сожалеет о том, что люди все поражают свои серверы, как сумасшедшие, для загрузки схем в миллиарды раз. К сожалению, практически ни одна стандартная библиотека XML не получает этого права, все они снова и снова попадают на серверы.
Проблема с DTD особенно серьезна, поскольку DTD могут включать объявления общих объектов (для таких вещей, как &
-> &), на которые фактически может ссылаться XML-файл. Поэтому, если ваш парсер решит отказаться от загрузки DTD, а XML использует ссылки на общие сущности, parsing может фактически завершиться неудачей.
Единственным решением этой проблемы будет прозрачный распознаватель сущности кэширования, который поместит загруженные файлы в некоторый архив в путь поиска библиотеки, чтобы этот архив был динамически создан и почти автоматически был связан с любыми распространенными дистрибутивами программного обеспечения. Но даже в Java-мире нет ни одного приличного такого EntityResolver, плавающего, конечно, не встроенного ни в что из основания Apache.
Попробуйте что-то вроде этого:
XmlDocument doc = new XmlDocument(); using (StringReader sr = new StringReader(xml)) using (XmlReader reader = XmlReader.Create(sr, new XmlReaderSettings())) { doc.Load(reader); }
Следует отметить, что XmlReaderSettings по умолчанию имеет свойство ProhibitDtd , равное true.
Используйте XMLReader
для загрузки документа и установите для свойства ValidationType
для параметров чтения значение None
.