Используйте StAX для чтения DTD из одного XML-документа и записи в другой

Итак, я выполняю некоторую очистку данных в серии XML-документов с использованием StAX. Я хочу, по сути, прочитать документ и выдать тот же самый документ с несколькими отсутствующими тегами. У меня проблема в том, что я не вывожу правильный XML.

Вы можете увидеть мой вывод слева и исходный документ справа [здесь] (http://imgur.com/a/oFxZd). Изображение внизу также является результатом xmllint -valid. Как видите, там написано, что DTD не найдено, а в конце документа есть дополнительный контент.

Мой код для реализации писателя таков

public XMLEventWriter setUpWriter(File blah) throws FileNotFoundException,                XMLStreamException {
    newFileName = thef.getName().substring(0, thef.getName().indexOf("_") + 1);

    try {
        writer = outputFactory
                .createXMLEventWriter(new FileOutputStream(newFileName + "mush.xml"), "UTF-8");

    } catch (XMLStreamException ex) {
        ex.printStackTrace();
        System.out.println("There was an XML Stream Exception, whatever that means for writer");
    }
    //outputFactory.setProperty("escapeCharacters", false);
    eventFactory = XMLEventFactory.newInstance();
    StartDocument startDocument = eventFactory.createStartDocument();

    writer.add(startDocument);
    //writer.add("<!DOCTYPE DjVuXML>");
    return writer;
}

Это мой код, который обрабатывает фактическое письмо.

 if (event.isStartElement()) { //first it looks for start elements
            StartElement se = event.asStartElement();
            if ("OBJECT".equals(se.getName().getLocalPart())) {
                writer.add(se);
            } else if ("MAP".equals(se.getName().getLocalPart())) {
                writer.add(se);
    } else if ("PARAM".equals(se.getName().getLocalPart())) {
                writer.add(se);
            } else if ("LINE".equals(se.getName().getLocalPart())) {
                writer.add(se);
            } else if ("DjVuXML".equals(se.getName().getLocalPart())) {
                writer.add(se);
            }else if ("WORD".equals(se.getName().getLocalPart())) {
                    word.text = reader.getElementText();

                    EndElement wordEnd = eventFactory.createEndElement("", "", "WORD");
                    writer.add(se);
                    Characters characters = eventFactory.createCharacters(word.text);
                    writer.add(characters);
                    writer.add(wordEnd);
                }

            }

        } else if (event.isEndElement()) {

            EndElement ee = event.asEndElement();
            if ("MAP".equals(ee.getName().getLocalPart())) {
                writer.add(ee);

            } else if ("DjVuXML".equals(ee.getName().getLocalPart())) {
                writer.add(ee);
            } else if ("LINE".equals(ee.getName().getLocalPart())) {
                writer.add(ee);
            }
            else if ("BODY".equals(ee.getName().getLocalPart())) {
                writer.add(ee);
            }
        }

    }
    writer.flush();
    writer.close();

Теперь, когда мы разобрались с этим, мой вопрос двоякий:

1) Является ли мой вывод недействительным, потому что в нем отсутствует DTD?

1a) если да, как включить DTD? Даже если нет, скажи мне, это меня беспокоит

2) Если это не DTD, то как, черт возьми, мне сделать эту вещь действительной.

Спасибо за вашу помощь!!


person Ben Zifkin    schedule 04.12.2014    source источник


Ответы (1)


1) Является ли мой вывод недействительным, потому что в нем отсутствует DTD?

Краткий ответ: в теории может быть да, а может и нет; на практике да.

В спецификации XML допустимость определяется следующим образом:

Документ XML действителен, если он имеет связанное объявление типа документа и если документ соответствует ограничениям, выраженным в нем.

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

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

На практике, если вы не сообщите проверяющему синтаксическому анализатору, где найти DTD для проверки, у синтаксического анализатора не будет иного выбора, кроме как выбрать второй, более строгий подход. Как он может проверить документ, если не может найти DTD? (Некоторые проверяющие синтаксические анализаторы принимают параметры времени выполнения для указания на DTD, другие — нет.)

1a) если да, как включить DTD? Даже если нет, скажи мне, это меня беспокоит

Судя по JavaDocs для эталонной реализации StAX, writeDTD(string) был вашим другом.

2) Если это не DTD, то как, черт возьми, мне сделать эту вещь действительной.

Если вы получаете сообщение о «дополнительном содержании», вполне вероятно, что ваш вывод не только недействителен, но и неправильно сформирован. Проверьте и исправьте это в первую очередь.

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

person C. M. Sperberg-McQueen    schedule 08.12.2014