Java изменить и переместить нестандартный XML-файл - PullRequest
2 голосов
/ 11 декабря 2008

Я использую стороннее приложение и хотел бы изменить один из его файлов. Файл хранится в формате XML, но с недопустимым типом документа.

Когда я пытаюсь читать, использую it ошибки из-за того, что doctype содержит «file: ///ReportWiz.dtd» (как показано, с кавычками), и я получаю исключение для не могу найти файл. Есть ли способ сказать докулеру игнорировать это? Я пытался установить значение false для false и setNamespaceAware для false для DocumentBuilderFactory.

Единственные решения, о которых я могу думать, это

  • копируйте файл построчно в новый файл, пропуская строку, вызывающую сбой, делайте то, что мне нужно, затем копируйте в другой новый файл и вставляйте строку, в которой нарушена, или
  • делает в основном то же самое, что и выше, но работает с FileStream некоторого вида (хотя мне не ясно, как я мог бы сделать это .. помощь?)
DocumentBuilderFactory docFactory = DocumentBuilderFactory
                    .newInstance();
docFactory.setValidating(false);
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(file);

Ответы [ 5 ]

4 голосов
/ 11 декабря 2008

Скажите вашей DocumentBuilderFactory игнорировать объявление DTD следующим образом:

docFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

См. здесь для списка доступных функций.

Вам также может показаться, что с JDOM работать намного проще, чем с org.w3c.dom:

org.jdom.input.SAXBuilder builder = new SAXBuilder();
builder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
org.jdom.Document doc = builder.build(file);
2 голосов
/ 11 декабря 2008

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

    EntityResolver er = new EntityResolver() {
        @Override
        public InputSource resolveEntity(String publicId, String systemId)
                throws SAXException, IOException {
            if ("file:///ReportWiz.dtd".equals(systemId)) {
                System.out.println(systemId);
                InputStream zeroData = new ByteArrayInputStream(new byte[0]);
                return new InputSource(zeroData);
            }
            return null;
        }
    };
1 голос
/ 11 декабря 2008

Моя первая мысль была связана с этим как с потоком. Вы можете создать новый адаптер на каком-то уровне и просто скопировать ввод в вывод, за исключением оскорбительного текста.

Если файл короткий (менее половины гигабайта или около того), вы также можете прочитать все это в байтовом массиве и внести в него свои изменения, а затем создать новый поток из байтового массива в свой конструктор.

Это преимущество удивительно громоздкого способа обработки потоков в Java: на самом деле вы обладаете большой гибкостью.

0 голосов
/ 07 июля 2015

, если вы не хотите считать, что синтаксическим анализатором является xerces, и хотите общее решение, см. this

0 голосов
/ 11 декабря 2008

Еще одна вещь, которую я обсуждал, - это сохранить весь файл в строку, затем выполнить мои манипуляции и связать строку с файлом. Ничто из этого не кажется чистым или простым, но как лучше всего это сделать? 1001 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...