Org.xml.sax.SAXParseException: ссылка на объект "T" должна заканчиваться символом ';' ограничитель
Я пытаюсь проанализировать XML файл, в котором содержатся некоторые специальные символы, такие как "&" используя парсер DOM. Я получаю исключение saxparse "ссылка на объект должна заканчиваться разделителем". Есть ли способ преодолеть это исключение, так как я не могу изменить файл XML, чтобы удалить специальные символы, поскольку он поступает из другого приложения. Пожалуйста, предложите способ проанализировать этот XML файл, чтобы получить корневой элемент?
Заранее спасибо
Это часть XML, которую я анализирую
<P>EDTA/THAM WASH
</P>
<P>jhc ^ 72. METER SOLVENT: Meter 21 LITERS of R. O. WATER through the add line into
FT-250. Start agitator.
</P>
<P>R. O. WATER <ZLl LITERS </P>
<P>• NOTE: The following is a tool control operation. The area within 10 feet of any open vessel or container is under tool control. </P>
<P>-af . 73. CHARGE SOLIDS: Remove any unnecessary items from the tool controlled area. Indicate the numbers of each item that will remain in the tool controlled area during the operation in the IN box of the Tool Control Log. </P>
<P>^___y_ a. To minimize the potential for cross contamination, confirm that no other solids are being charged or packaged in adjacent equipment. </P>
<P>kk k WARNING: Wear protective gloves, air jacket and use local exhaust when handling TROMETHAMINE USP (189400) (THAM) (K-l--Irritant!). The THAM may be dusty. </P>
<P>-<&^b . Charge 2.1 KG of TROMETHAMINE USP (189400) (THAM) into FT-250 through the top. </P>
<P>TROMETHAMINE USP (189400) (THAM) </P>
<P>Scale ID: / / 7S </P>
<P>LotNo.: qy/o^yo^ </P>
<P>Gross: ^ . S </P>
<P>Tare: 10 ,1 </P>
<P>Net: J^l </P>
<P>Total: JL'J </P>
<P><Figure ActualText="&T ">
<ImageData src="images/17PT 07009K_img_1.jpg"/>
&T </Figure>
Checked by </P>
Ответы
Ответ 1
Как заявили другие, ваш XML определенно недействителен. Однако, если вы не можете изменить создающее приложение и можете добавить шаг очистки, то следующее должно очистить XML:
String clean = xml.replaceAll( "&([^;]+(?!(?:\\w|;)))", "&$1" );
То, что делает это регулярное выражение, ищет любые плохо сформированные ссылки на объекты и ускоряет амперсанд.
В частности, (?!(?:\\w|;))
- это негативный прогноз, который делает остановку совпадения ничем, кроме символа слова (a-z, 0-9), а не точкой с запятой. Таким образом, все регулярное выражение захватывает все, что есть, и это не так; до первого символа, отличного от слова, без полуколонии.
В нем помещается все, кроме амперсанда в первой группе захвата, так что на него можно ссылаться в строке replace. Что $1.
Обратите внимание, что это не будет исправлять ссылки, которые выглядят так, как будто они действительны, но не являются. Например, если у вас есть & T; что вообще может вызвать различную ошибку, если XML не определяет сущность.
Ответ 2
Я не уверен, что понимаю этот вопрос. Насколько мне известно, если вы не находитесь внутри CDATA
, голые символы &
без закрытия ;
являются недопустимыми.
Если это не так для вашего XML файла, то оно недействительно, и вам нужно будет найти другой способ его разбора или исправить его до того, как SAX завладеет им.
Если я что-то не понимаю, вы, вероятно, должны опубликовать образец фактического XML, чтобы мы могли продолжить.
Update:
Похоже:
Figure ActualText="&T "
является нарушающей линией. Этот раздел находится в пределах CDATA
или нет? Если нет, это недействительный XML, и вы не должны ожидать, что SAX сможет его обработать.
Вам понадобится:
- изменить созданное приложение; или
- исправить его перед загрузкой SAX (если вы не можете изменить это приложение) на что-то вроде "
Figure ActualText="&T "
"; или
- найдите не-SAX-метод для синтаксического анализа.
Ответ 3
Некоторые из вас могут быть знакомы с ОШИБКОЙ "Ссылка на объект XX должна заканчиваться на" разделитель "при добавлении или изменении любой части кода на ваши XML-шаблоны. Даже иногда я получаю эту ОШИБКУ, когда я пытаюсь изменить или добавить некоторые коды в свои блоговые блоги блога (XML).
В большинстве случаев эти типы ошибок возникают, когда мы добавляем сторонние баннеры или виджеты в наши XML-шаблоны. Мы можем легко исправить эту ОШИБКУ, сделав небольшое изменение в добавляемом фрагменте кода!
Just replace "&" with "&" in your HTML/Javascript code!
Пример
Original Code:
<!– Begin Code –>
<script src="http://XXXXXX.com/XXX.php?sid=XXX&br=XXX&dk=XXXXXXXXXXXX" type="text/javascript"/>
<!– End Code –>
Altered Code:
<!– Begin Code –>
<script src="http://XXXXXX.com/XXX.php?sid=XXX&br=XXX&dk=XXXXXXXXXXXX" type="text/javascript"/>
<!– End Code –>
Ответ 4
Основываясь на ответе выше от PSpeed, следующее регулярное выражение replaceAll и текст замены заменят все неэкранированные амперсанды экранированными амперсандами.
String clean = xml.replaceAll( ("(&(?!amp;))", "&") );
Образец - это отрицательный lookahead для сопоставления на любых амперсандах, которые еще не были экранированы, а строка замены - просто экранированный амперсанд. Это можно оптимизировать для повышения производительности, используя статически скомпилированный шаблон.
private final static Pattern unescapedAmpersands = Pattern.compile("(&(?!amp;))");
...
Matcher m = unescapedAmpersands.matcher(xml);
String xmlWithAmpersandsEscaped = m.replaceAll("&");
Ответ 5
В качестве обходного пути вы можете:
- Замените все вхождения
&
на &
в исходном входе;
- Разберите его;
- В коде, обрабатывающем результат, обработайте случай, когда теперь вы получаете экранированные символы (например,
<
вместо <
).
В зависимости от используемого анализатора вы также можете попытаться найти класс, ответственный за разбор и отмену &
-strings, и посмотреть, можете ли вы расширить его/предоставить свой собственный резольвер. (То, что я говорю, очень расплывчато, но особенности зависят от инструментов, которые вы используете.)
Ответ 6
Ваш вход недопустим. В частности, у вас не может быть "&" символ в значении атрибута, если он не является частью хорошо сформированной ссылки сущности символа.
AFAIK, у вас есть два варианта:
- Напишите "не точно XML" парсер самостоятельно. Я серьезно сомневаюсь, что вы найдете существующий. Любой уважающий себя парсер XML отклонит недопустимый ввод.
- Исправить все, что создает этот (так называемый) XML, чтобы он не помещал случайные "&" символов в местах, где они не допускаются. Это очень просто. Когда вы строите XML, замените '&' символ, который еще не является частью символьной ссылки с '& amp;'
Ответ 7
Просто замените &
на &
и он будет работать.
Ответ 8
Это будет работать, если вы используете приведенную ниже команду перед публикацией.
пожалуйста, укажите имя вашего XML файла в приведенной ниже команде
sed -i "s/&/;/g" *.xml
Ответ 9
В дополнение к ответу @PSpeed, вот полное решение (SAX-парсер):
try {
InputStream xmlStreamToParse = blob.getBinaryStream();
// Clean
BufferedReader br = new BufferedReader(new InputStreamReader(xmlStreamToParse));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line.replaceAll("&([^;]+(?!(?:\\w|;)))", "&$1")); // or whatever you want to clean
}
InputStream stream = org.apache.commons.io.IOUtils.toInputStream(sb.toString(), "UTF-8");
// Parsing
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
saxFactory.setNamespaceAware(true);
SAXParser theParser = saxFactory.newSAXParser();
XMLReader xmlReader = theParser.getXMLReader();
LicenceXMLHandler licence = new LicenceXMLHandler();
xmlReader.setContentHandler(licence);
xmlReader.parse(new InputSource(stream));
} catch (SQLException | SAXException | IOException | ParserConfigurationException e) {
log.error("Error: " + e);
}
Пояснения:
- Преобразовать BLOB-объект в InputStream
- Очистить блоб
- Разбор файла (LicenceXMLHandler - класс анализатора)