Как читать / записывать значение символов Java ASCII с XMLStreamReader? - PullRequest
1 голос
/ 21 октября 2019

Я хотел бы использовать XMLStreamReader для чтения XML-файла, содержащего ASCII-коды с горизонтальной вкладкой 	, например:

<tag>foo&#009;bar</tag>

и распечатывать или записывать его обратнов другой XML-файл.

Google говорит мне установить javax.xml.stream.isCoalescing в true в XMLInputFactory, но мой тестовый код ниже не работает должным образом.

public static void main(String[] args) throws IOException, XMLStreamException {
    XMLInputFactory factory = XMLInputFactory.newInstance();
    factory.setProperty(factory.IS_COALESCING, true);

    System.out.println("IS_COALESCING supported ? " + factory.isPropertySupported(factory.IS_COALESCING));
    System.out.println("factory IS_COALESCING value is " +factory.getProperty(factory.IS_COALESCING));

    String rawString = "<tag>foo&#009;bar</tag>";
    XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(rawString));
    System.out.println("reader IS_COALESCING value is " +reader.getProperty(factory.IS_COALESCING));

    PrintWriter pw = new PrintWriter(System.out, true);
    while (reader.hasNext())
    {
        reader.next();
        pw.print(reader.getEventType());
        if (reader.hasText())
            pw.append(' ').append(reader.getText());
        pw.println();
    }
}

Выводэто

IS_COALESCING supported ? true
factory IS_COALESCING value is true
reader IS_COALESCING value is true
1
4 foo   bar
2
8

Но я хочу сохранить ту же горизонтальную вкладку, как:

IS_COALESCING supported ? true
factory IS_COALESCING value is true
reader IS_COALESCING value is true
1
4 foo&#009;bar
2
8

Что мне здесь не хватает? спасибо

1 Ответ

1 голос
/ 29 октября 2019

Из того, что я вижу, часть синтаксического анализа правильная - она ​​просто не напечатана, как вы себе это представляете. Ваша кодировка Unicode интерпретируется читателем XML как \t и соответственно представлена ​​в Java.

Используя XmlEscapers в Guava, я могу создать нечто похожее на то, что вы хотите иметь:

public class Test {
    public static void main(String[] args) throws IOException, XMLStreamException {
        XMLInputFactory factory = XMLInputFactory.newInstance();
        factory.setProperty(XMLInputFactory.IS_COALESCING, true);

        System.out.println("IS_COALESCING supported ? " + factory.isPropertySupported(XMLInputFactory.IS_COALESCING));
        System.out.println("factory IS_COALESCING value is " + factory.getProperty(XMLInputFactory.IS_COALESCING));

        String rawString = "<tag>foo&#009;bar</tag>";
        XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(rawString));
        System.out.println("reader IS_COALESCING value is " + reader.getProperty(XMLInputFactory.IS_COALESCING));

        PrintWriter pw = new PrintWriter(System.out, true);
        while (reader.hasNext()) {
            reader.next();
            pw.print(reader.getEventType());
            if (reader.hasText()) {
                pw.append(' ').append(XmlEscapers.xmlAttributeEscaper().escape(reader.getText()));
            }
            pw.println();
        }
    }

Вывод выглядит так:

IS_COALESCING supported ? true
factory IS_COALESCING value is true
reader IS_COALESCING value is true
1
4 foo&#x9;bar
2
8

Некоторые замечания к этому:

  • Сама библиотека помечена как нестабильная, возможны другие альтернативы
  • \t не нужно экранировать в XML-контенте, поэтому мне пришлось выбирать конвертер атрибутов. Хотя это работает, могут возникнуть некоторые побочные эффекты
  • Действительно ли требуется 100% -ная копия контента? В противном случае я бы предложил библиотекам XML выполнить свою работу и создать правильную кодировку.
    • Если вы действительно хотите иметь копию 1: 1, можно ли указать входные данные как CDATA?
...