Самый простой способ - заменить зарезервированные символы xml соответствующими объектами xml. Вы можете сделать это вручную:
content.replaceAll("&", "&");
Если вы не хотите изменять строку перед ее анализом, я мог бы предложить вам другой способ, используя SaxParser
, но это решение более сложное. В основном вы должны:
- написать
LexicalHandler
в
комбинация с ContentHandler
- попросить парсер продолжить
выполнение после фатальной ошибки (
ErrorHandler
недостаточно)
- обрабатывать необъявленные сущности как простые
Текст
UPDATE
Согласно вашему комментарию, я собираюсь добавить некоторые детали, касающиеся второго решения. Я написал класс, который расширяет DefaulHandler
(реализация по умолчанию EntityResolver
, DTDHandler
, ContentHandler
и ErrorHandler
) и реализует LexicalHandler
. Я расширил метод ErrorHandler
fatalError
(мои реализации ничего не делают вместо генерации исключения) и метод ContentHandler
characters
, который работает в сочетании с startEntity
методом LexicalHandler
.
public class MyHandler extends DefaultHandler implements LexicalHandler {
private String currentEntity = null;
@Override
public void fatalError(SAXParseException e) throws SAXException {
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String content = new String(ch, start, length);
if (currentEntity != null) {
content = "&" + currentEntity + content;
currentEntity = null;
}
System.out.print(content);
}
@Override
public void startEntity(String name) throws SAXException {
currentEntity = name;
}
@Override
public void endEntity(String name) throws SAXException {
}
@Override
public void startDTD(String name, String publicId, String systemId)
throws SAXException {
}
@Override
public void endDTD() throws SAXException {
}
@Override
public void startCDATA() throws SAXException {
}
@Override
public void endCDATA() throws SAXException {
}
@Override
public void comment(char[] ch, int start, int length) throws SAXException {
}
}
Это моя основная задача, которая анализирует ваш xml неправильно сформированный. Очень важно setFeature
, потому что без него парсер выдает SaxParseException
несмотря на пустую реализацию ErrorHandler
.
public static void main(String[] args) throws ParserConfigurationException,
SAXException, IOException {
String xml = "<div class='video yt'><div class='yt_url'>http://www.youtube.com/watch?v=U_QLu_Twd0g&feature=abcde_gdata</div></div>";
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
MyHandler myHandler = new MyHandler();
xmlReader.setContentHandler(myHandler);
xmlReader.setErrorHandler(myHandler);
xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler",
myHandler);
xmlReader.setFeature(
"http://apache.org/xml/features/continue-after-fatal-error",
true);
xmlReader.parse(new InputSource(new StringReader(xml)));
}
Эта главная распечатывает содержимое вашего элемента div, который содержит ошибку:
http://www.youtube.com/watch?v=U_QLu_Twd0g&feature=abcde_gdata
Имейте в виду, что это пример, который работает с вашим вводом, возможно, вам придется его завершить ... например, если у вас правильно экранированы некоторые символы, вы должны добавить несколько строк кода для обработки этой ситуации и т. Д.
Надеюсь, это поможет.