Отключить разрешение сущностей XML в JDOM / DOM - PullRequest
4 голосов
/ 28 июля 2011

Я пишу Java-приложение для постобработки XML-файлов. Эти xml-файлы взяты из RDF-экспорта Semantic Mediawiki, поэтому они имеют синтаксис rdf / xml.

Моя проблема заключается в следующем: Когда я читаю xml-файл, все сущности в этом файле преобразуются в их значение, указанное в Doctype. Например в Doctype у меня есть

<!DOCTYPE rdf:RDF[
<!ENTITY wiki 'http://example.org/smartgrid/index.php/Special:URIResolver/'>
..
]>

и в корневом элементе

<rdf:RDF
xmlns:wiki="&wiki;"
..
>

Это значит

<swivt:Subject rdf:about="&wiki;Main_Page">

становится

<swivt:Subject rdf:about="http://example.org/smartgrid/index.php/Special:URIResolver/Main_Page">

Я пытался использовать JDOM и стандартный Java DOM. Код, который я думаю, уместен здесь для стандартного DOM:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setExpandEntityReferences(false);
        factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

и для JDOM

SAXBuilder builder = new SAXBuilder();
    builder.setExpandEntities(false); //Retain Entities
    builder.setValidation(false);
    builder.setFeature("http://xml.org/sax/features/resolve-dtd-uris", false);

Но сущности разрешаются во всем XML-документе. Я что-то пропустил? Часы поиска привели меня только к командам ExpandEntities, но, похоже, они не работают.

Любая подсказка высоко ценится:)

Ответы [ 3 ]

6 голосов
/ 15 января 2015

Я рекомендую JDOM FAQ:

[http://www.jdom.org/docs/faq.html#a0350]

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

Даже когда проверка отключена, анализатор XML по умолчанию будет загружать внешний файл DTD, чтобы проанализировать DTD для внешнегодекларации объекта.Xerces имеет функцию для отключения этого поведения с именем "http://apache.org/xml/features/nonvalidating/load-external-dtd", и если вы знаете, что используете Xerces, вы можете установить эту функцию на компоновщике.

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

Если вы используете другоеПарсер, как Crimson, лучше всего настроить EntityResolver, который разрешает DTD без фактического чтения отдельного файла.

import org.xml.sax.*;
import java.io.*;

public class NoOpEntityResolver implements EntityResolver {
  public InputSource resolveEntity(String publicId, String systemId) {
    return new InputSource(new StringBufferInputStream(""));
  }
}

Затем в компоновщике ...

builder.setEntityResolver(new NoOpEntityResolver());

Тамявляется недостатком этого подхода. Любые объекты в документе будут преобразованы в пустую строку и фактически исчезнут. Если в вашем документе есть объекты, вам нужно установить код ExpExpandEntities (false) и убедиться, что EntityResolver подавляет только DocType.

0 голосов
/ 29 июля 2011

Я нашел различные подсказки, такие как , этот , которые говорят, что вы не можете отключить расширение сущности в атрибутах. Я не уверен, что предположить, что это не уродливо. Например, вы могли бы использовать EntityResolver, который привел бы к "нулевому" DTD - который определил расширение "wiki" как "& wiki;". Кажется, должен быть лучший путь!

0 голосов
/ 28 июля 2011

Я считаю, что если проверка (функция http://xml.org/sax/features/validation) верна, она переопределяет setExpandEntities(false).Попробуйте также отключить проверку, установив для этой функции значение false.

...