Обычно мы не удаляем элементы doctype вручную, а параметризируем синтаксический анализатор, чтобы он игнорировал их. Как это сделать, к сожалению, сильно зависит от того, какой это парсер. В JAXB это можно сделать так:
XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
// xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("test.xml"));
Строка с XMLInputFactory.SUPPORT_DTD
полностью отключит doctype. Если я правильно помню, все определенные сущности будут заменены пустыми строками (не верьте мне на слово - проверьте это).
Строка с XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES
есть, потому что я обнаружил, что * Парсеры 1015 * в конфигурации Java по умолчанию не уязвимы для атак XML бомб (например, той, что у вас есть в XML). Атака остановится после 60k итераций довольно быстро (помните - не верьте мне на слово). Поэтому после долгого тестирования я решил останавливать только внешние сущности, которые являются помехой и небезопасным по умолчанию в Java.
Если вы используете не JAXB, а JDOM, то предотвращение внешних сущностей будет выглядеть иначе. :
SAXBuilder builder = new SAXBuilder();
File xmlFile = new File("test.xml");
builder.setExpandEntities(false);
Document document = builder.build(xmlFile);
В Dom4J тоже по-другому:
SAXReader reader = new SAXReader();
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
Document document = reader.read("test.xml");