Как мне легко изменить тип документа XML в Java? - PullRequest
2 голосов
/ 17 ноября 2009

Вот моя проблема:

Моя программа получает файлы XML в качестве входных данных. Эти файлы могут иметь или не иметь декларацию xml, декларацию типа документа или декларацию сущности, но все они соответствуют одной и той же схеме. Когда моя программа получает новый файл, она должна проверить его и убедиться, что в нем есть такие объявления:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE my.doctype [
<!ENTITY % entity_file SYSTEM "my.entities.ent">
%entity_file;
]>

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

Как мне это сделать (желательно легко, используя стандартные библиотеки Java 6 и / или Apache)?

Ответы [ 3 ]

2 голосов
/ 17 ноября 2009

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

private Document copyDocument(Document document) {
    DocumentType origDoctype = document.getDoctype();
    DocumentType doctype = documentBuilder
        .getDOMImplementation().createDocumentType(origDoctype.getName(), 
                                                   origDoctype.getPublicId(),
                                                   origDoctype.getSystemId());
    Document copiedDoc = documentBuilder.getDOMImplementation().
        createDocument(null, origDoctype.getName(), doctype);
    // so we already have the top element, and we have to handle the kids.
    Element newDocElement = copiedDoc.getDocumentElement();
    Element oldDocElement = document.getDocumentElement();
    for (Node n = oldDocElement.getFirstChild(); n != null; n = n.getNextSibling()) {
        Node newNode = copiedDoc.importNode(n, true);
        newDocElement.appendChild(newNode);
    }

    return copiedDoc;
}
0 голосов
/ 17 ноября 2009

Зачем вам нужно "удалить все, что уже есть и добавить правильные объявления"?

Если вы используете файл XML для ввода, а не записываете его обратно в какой-либо форме, тогда подходящим решением будет создание EntityResolver.

Полное описание процесса: здесь , но следующий код показывает, как дать парсеру свое собственное DTD, независимо от того, что документ говорит, что хочет:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(true);
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new EntityResolver()
{
    public InputSource resolveEntity(String publicId, String systemId)
        throws SAXException, IOException
    {
        return new InputSource(new StringReader(dtd));
    }
});
0 голосов
/ 17 ноября 2009

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

...