Оставьте сущности как есть при разборе XML с помощью Woodstox - PullRequest
0 голосов
/ 13 февраля 2019

Я использую Woodstox для обработки XML, который содержит некоторые сущности (особенно >) в значении одного из узлов.Чтобы использовать крайний пример, это что-то вроде этого:

<parent>&nbsp; &lt; &nbsp; &gt; &amp; &quot; &apos; &nbsp;</parent>

Я испробовал множество различных вариантов конфигурации для обоих WstxInputFactory (IS_REPLACING_ENTITY_REFERENCES, P_TREAT_CHAR_REFS_AS_ENTS, P_CUSTOM_INTERNAL_ENTITIES ...) и WstxOutputFactory , но независимо от того, что я пытаюсь, вывод всегда будет выглядеть примерно так:

<parent>nbsp; &lt; nbsp; > &amp; " ' nbsp;</parent>

(&gt; преобразуется в >, &lt; остается прежним, &nbsp; теряет & ...)

Я читаю XML с XMLEventReader создан с помощью

XMLEventReader reader = wstxInputFactory.createXMLEventReader(new StringReader(fulltext));

после настройки WstxInputFactory .

Есть ли способ настроить Woodstox так, чтобы он просто игнорировал все сущности и выводил текстточно как было во входной строке?

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Прежде всего, вам нужно включить реальный код, поскольку «вывод всегда что-то вроде этого» не имеет смысла без объяснения того, как именно вы выводите анализируемый контент: вы можете печатать события, используя некоторую библиотеку или, возможно, используяПоток Woodstox или средство записи событий.

Второе: существует разница в XML между небольшим числом предопределенных объектов (lt, gt, apos, quot, amp) ипроизвольные определяемые пользователем объекты, такие как nbsp здесь.Бывшие вы можете использовать как есть, они уже определены;последние существуют, только если вы определили их в DTD.

Обработка двух групп также различна;первый всегда будет расширяться несмотря ни на что, и это в соответствии со спецификацией XML.Последний будет разрешен (если только разрешение не отключено), а затем расширен - или, если не определено, будет сгенерировано исключение.Вы также можете указать собственный распознаватель, как упомянуто в другом ответе;но это будет использоваться только для пользовательских сущностей (здесь &nbsp;).

В конце также полезно объяснить не то, что вы делаете, а то, что вы пытаетесь достичь.Это поможет предложить вещи лучше, чем конкретные вопросы о том, «как мне сделать X», что, возможно, не является подходящим способом.

А что касается конфигурации Woodstox, возможно, эта запись в блоге:

https://medium.com/@cowtowncoder/configuring-woodstox-xml-parser-woodstox-specific-properties-1ce5030a5173

поможет (как и 2 других в серии) - он охватывает существующие параметры конфигурации.

0 голосов
/ 14 февраля 2019

Основные пять сущностей XML (quot, amp, apos, lt, gt) будут всегда обрабатываться.Насколько я знаю, нет никакого способа получить их источник с помощью Sax.

Для других объектов вы можете обработать их вручную.Вы можете захватывать события до конца элемента и объединять значения:

    XMLInputFactory factory = WstxInputFactory.newInstance();
    factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE);
    XMLEventReader xmlr = factory.createXMLEventReader(
            this.getClass().getResourceAsStream(xmlFileName));

    String value = "";
    while (xmlr.hasNext()) {
        XMLEvent event = xmlr.nextEvent();
        if (event.isCharacters()) {
            value += event.asCharacters().getData();
        }
        if (event.isEntityReference()) {
            value += "&" + ((EntityReference) event).getName() + ";";
        }
        if (event.isEndElement()) {
            // Assign it to the right variable
            System.out.println(value);
            value = "";
        }
    }

Для вашего примера введите:

<parent>&nbsp; &lt; &nbsp; &gt; &amp; &quot; &apos; &nbsp;</parent>

Вывод будет:

&nbsp; < &nbsp; > & " ' &nbsp;

В противном случае, если вы хотите преобразовать все сущности, возможно, вы могли бы использовать пользовательский XmlResolver для необъявленных сущностей:

public class NaiveHtmlEntityResolver implements XMLResolver {

    private static final Map<String, String> ENTITIES = new HashMap<>();

    static {
        ENTITIES.put("nbsp", " ");
        ENTITIES.put("apos", "'");
        ENTITIES.put("quot", "\"");
        // and so on
    }

    @Override
    public Object resolveEntity(String publicID,
            String systemID,
            String baseURI,
            String namespace) throws XMLStreamException {
        if (publicID == null && systemID == null) {
            return ENTITIES.get(namespace);
        }
        return null;
    }
}

А затем сказать Woodstox, чтобы использовать его для необъявленных сущностей:

    factory.setProperty(WstxInputProperties.P_UNDECLARED_ENTITY_RESOLVER, new NaiveHtmlEntityResolver());
...