SAXReader не перезапускает символы - PullRequest
2 голосов
/ 12 февраля 2010

Я читаю XML-файл с помощью dom4j. Файл выглядит так:

...
<Field>&#13;&#10; hello, world...</Field>
...

Я прочитал файл с SAXReader в Document. Когда я использую getText() на узле, я получаю следующую строку:

\r\n hello, world...

Я выполняю некоторую обработку, а затем пишу другой файл, используя asXml(). Но символы не экранируются, как в исходном файле, что приводит к ошибке во внешней системе, использующей файл.

Как я могу избежать специального символа и иметь &#13;&#10; при записи файла?

Ответы [ 4 ]

1 голос
/ 12 февраля 2010

Это зависит от того, что вы получаете и чего хотите (см. Мой предыдущий комментарий.)

Программа чтения SAX не делает ничего плохого - ваш XML дает буквальный символ новой строки. Если вы управляете этим XML, то вместо символов новой строки вам нужно будет вставить символ \ (обратный слеш), следующий за символами «r» или «n» (или обоими). ​​

Если вы не контролируете этот XML, то вам нужно будет выполнить буквальное преобразование символа новой строки в "\ r \ n" после того, как вы вернете свою строку. В C # это было бы что-то вроде:

myString = myString.Replace("\r\n", "\\r\\n");
1 голос
/ 12 февраля 2010

XML-объекты абстрагируются в DOM. Контент предоставляется String без необходимости беспокоиться о кодировке, что в большинстве случаев является тем, что вам нужно.

Но SAX имеет некоторую поддержку для обработки сущностей. Вы можете попытаться создать XMLReader с пользовательским EntityResolver#resolveEntity и передать его в качестве параметра SAXReader. Но я подвиг это может не сработать:

Парсер вызовет этот метод перед открытием любого внешнего объекта кроме сущности документа верхнего уровня (включая внешнее подмножество DTD, внешние объекты, на которые есть ссылки в DTD и внешние объекты упоминается в документе элемент)

В противном случае вы можете попытаться настроить LexicalHandler для SAX таким образом, чтобы получать уведомления при обнаружении сущности. Javadoc для LexicalHandler#startEntity говорит:

Сообщить о начале какого-то внутреннего и внешние сущности XML.

Вы не сможете изменить разрешение, но это все равно может помочь.

EDIT

Вы должны читать и писать XML с SAXReader и XMLWriter, предоставленными dom4j. См. чтение XML-файла и запись XML-файла . Не используйте asXml() и сохраните файл самостоятельно.

FileOutputStream fos = new FileOutputStream("simple.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(fos, format);
writer.write(doc);
writer.flush();
1 голос
/ 12 февраля 2010

Вы не можете легко. Это не «побеги», это «сущности персонажей». Они являются фундаментальной частью XML. Xerces имеет очень сложную поддержку «неразобранных сущностей», но я сомневаюсь, что это применимо к ним, в отличие от видов, определенных в DTD.

0 голосов
/ 08 ноября 2016

Вы можете предварительно обработать входной поток, чтобы заменить &, например, на. [$AMPERSAND_CHARACTER$], затем выполните все с помощью dom4j и постобработайте выходной поток, выполнив обратную подстановку.

Пример (с использованием streamflyer ):

import com.github.rwitzel.streamflyer.util.ModifyingReaderFactory;
import com.github.rwitzel.streamflyer.util.ModifyingWriterFactory;

// Pre-process
Reader originalReader = new InputStreamReader(myInputStream, "utf-8");
Reader modifyingReader = new ModifyingReaderFactory().createRegexModifyingReader(originalReader, "&", "[\\$AMPERSAND_CHARACTER\\$]");

// Read and modify XML via dom4j
SAXReader xmlReader = new SAXReader();
Document xmlDocument = xmlReader.read(modifyingReader);
// ...

// Post-process
Writer originalWriter = new OutputStreamWriter(myOutputStream, "utf-8");
Writer modifyingWriter = new ModifyingWriterFactory().createRegexModifyingWriter(originalWriter, "\\[\\$AMPERSAND_CHARACTER\\$\\]", "&");

// Write to output stream
OutputFormat xmlOutputFormat = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(modifyingWriter, xmlOutputFormat);
xmlWriter.write(xmlDocument);
xmlWriter.close();

Вы также можете использовать FilterInputStream / FilterOutputStream , PipedInputStream / PipedOutputStream или ProxyInputStream / ProxyOutputStream для предварительной и последующей обработки.

...