Проблема синтаксического анализа XML с символом "&" в тексте элемента

У меня есть следующий код:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(inputXml)));

И шаг синтаксического анализа бросает:

SAXParseException: The entity name must immediately follow 
                   the '&' in the entity reference

из-за следующего "&" в моем inputXml:

<Line1>Day & Night</Line1>

Я не контролирую входящий XML. Как я могу правильно/правильно разобрать это?

Ответ 1

Довольно просто вход XML не является допустимым XML. Объект должен быть закодирован, то есть:

<Line1>Day &amp; Night</Line1>

В принципе, нет "правильного" способа исправить это, кроме как сообщить поставщику XML, что они дают вам мусор и заставляют их исправлять его. Если вы находитесь в какой-то ужасной ситуации, когда вам нужно только разобраться с этим, тогда ваш подход будет зависеть от того, какой диапазон значений вы ожидаете получить.

Если в документе вообще нет сущностей, замену регулярного выражения & на &amp; перед обработкой сделало бы трюк. Но если они отправляют некоторые объекты правильно, вы должны исключить их из соответствия. И по редкой случайности, что они действительно хотели отправить код сущности (т.е. Отправлено &amp;, но означало &amp;amp;), вам будет совершенно не повезло.

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

Ответ 2

Ваш XML-вход недействителен XML; к сожалению, вы не можете реально использовать синтаксический анализатор XML для анализа этого.

Вам необходимо предварительно обработать текст перед передачей его в парсер XML. Несмотря на то, что вы можете заменить строку, заменив '& ' на '&amp; ', это не будет ловить каждое появление & во входном файле, но вы можете придумать что-то, что делает.

Ответ 3

Я использовал структуру Tidy перед XML-анализом

final StringWriter errorMessages = new StringWriter();
final String res = new TidyChecker().doCheck(html, errorMessages);
...
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(addRoot(html))));  
...

И все Ok

Ответ 4

есть inputXML строка? Затем используйте это:

inputXML = inputXML.replaceAll("&\\s+", "&amp;");