Есть ли более простой способ, чтобы JAXB мог принимать теги XML с этой ошибкой attr1 = "value" attr2?
Нет, потому что это не ошибка.
XML, содержащий attr1="value"attr2
, неправильно сформирован, поэтому JAXB не сможет его проанализировать и выдаст исключение, указывающее на фатальную невосстановимую ошибку.
Если вы ожидаете XML-ish данные такого рода, и вы не можете их контролировать (вы получаете их от третьей стороны), тогда ваше решение кажется ОК.Однако, если бы я был вами, я бы связался с этой третьей стороной и сказал бы им, что они извергают недопустимый XML, и это не слишком профессионально.
Альтернативой замене строк регулярными выражениями может быть что-то вроде этого (но это не совсем просто):
public String toWellFormed(String xml) throws IOException, SAXException {
StringBuilder sb = new StringBuilder(xml);
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler(null);
reader.setErrorHandler(null);
boolean threw = true;
while (threw)
try {
reader.parse(new InputSource(new StringReader(sb.toString())));
threw = false;
} catch (SAXParseException ex) {
if (ex.getMessage().contains("must be followed by either attribute specifications")) {
threw = true;
int line = ex.getLineNumber();
int column = ex.getColumnNumber();
sb.insert(line * column - 1, ' ');
} else
throw ex;
}
return sb.toString();
}
String malformedXml = "<test a='a'b='b'c='c'/>";
String wellFormedXml = toWellFormed(malformedXml);
"<test a='a'b='b'c='c'/>".equals(wellFormedXml);
JAXB Unmarshaller
должен уметь обрабатывать wellFormedXml
после процесса.
Если замена содержимого регулярными выражениями достаточно хороша, поскольку ваши данные не содержат слишком много содержимого для поиска и содержат только конкретную ошибку форматирования, которую вы описали, не используйтеКонечно, мое решение, но если вы ожидаете больше ошибок форматирования, вы можете использовать что-то вроде этого.
Обратите внимание, что я явно установил обработчик ошибок читателя и содержимого на null
.Это потому, что из-за искаженного XML они никогда не называются;читатель рано потерпит неудачу, потому что это фатальная, невосстановимая ошибка.Это, конечно, очень плохо для нас, потому что если документ содержит 10 ошибок, как вы описали, тогда мой метод анализирует XML 10 раз, пока не найдет каждую ошибку.Мне неизвестен XML-анализатор в JDK, который бы сообщал об ошибках форматирования и продолжал синтаксический анализ (сообщая о каждой ошибке во время процесса).
Используя правильный ErrorHandler
, вы могли быобрабатывать предупреждения и ошибки изящно, однако фатальные ошибки не могут быть обработаны даже с ErrorHandler
(после вызова метода fatalError
обработка останавливается).
Использование XMLFilter
реализация также не поможет вам, потому что если вы просто используете класс XMLFilterImpl
по умолчанию, который перенаправляет все его вызовы делегату XMLReader
, то вы столкнетесь с той же проблемой, что и раньше: при первой ошибке обработка останавливается.На самом деле, если вы хотите что-то реализовать, то реализуйте интерфейс XMLReader
напрямую (XMLFilter
добавляет только методы setParent
и getParent
- плохой дизайн, если вы спросите меня).Но реализация XMLReader
, которая может анализировать искаженный XML, вероятно, будет утомительной.