Как легко изменить тип документа XML-документа в Java?

StackOverflow https://stackoverflow.com/questions/1745794

  •  20-09-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

Если вы используете 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));
    }
});

Другие советы

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

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;
}

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top