Замена символов в неправильно сформированном теле XML
В (Java) коде, над которым я работаю, я иногда имею дело с не правильно сформированным XML (представленным как Java String
), такие как:
<root>
<foo>
bar & baz < quux
</foo>
</root>
Так как этот XML в конечном итоге должен быть распакован (с использованием JAXB), очевидно, что этот XML как есть, выдаст исключение при распаковке.
Какой лучший способ заменить &
и <
своим персонажем сущностей? За &
это так же просто, как:
xml.replaceAll("&", "&")
Однако для <
символ, это немного сложно, так как, очевидно, я не хочу заменять <
это используется для открытия тега XML 'скобка'.
Кроме сканирования строки и замены вручную <
в теле XML с <
Какой другой вариант вы можете предложить?
3 ответа
Честно говоря, лучший способ исправить искаженный XML - это отправить его обратно тому, кто его создал, и попросить вместо этого выслать вам правильно сформированный XML. Вы показываете тривиальный пример, который потенциально может иметь решение, но общий метод исправления искаженного XML будет ужасной работой.
А так как синтаксические анализаторы XML не обязаны обрабатывать искаженный XML, ваш синтаксический анализатор также не требуется. Просто не делай этого.
Я думаю, вам нужно больше логики заранее. Лучше всего сначала найти все реальные теги, используя регулярное выражение типа "(<[^>] +>)", и заменять только текст вне этих совпадений, но, очевидно, вы не сможете использовать метод replaceAll. Это будет больше работа сантехника...
Хотя это старый пост, но я подумал, что это может помочь кому-то еще... У меня было такое же требование / проблема, и я мог решить, используя следующий код.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class XMLTest {
/**
* @param args
*/
public static void main(String[] args) {
String xml = "<xml><body>" +
"<message>something < between <<< somthing </message>" +
"<text> testing >> > testing </text>" +
"</body></xml>";
Pattern replaceGTPattern = Pattern.compile(">[^<](.[^<]*)(>)+");
Matcher m = replaceGTPattern.matcher(xml);
String replacement;
StringBuffer intermXml = new StringBuffer();
while(m.find()){
replacement = ">"+m.group(0).substring(1).replaceAll(">", ";>");
m.appendReplacement(intermXml,replacement);
}
m.appendTail(intermXml);
Pattern replaceLTPattern = Pattern.compile("<(.[^>]*)(<)+");
m = replaceLTPattern.matcher(intermXml);
StringBuffer finalXml = new StringBuffer();
while(m.find()){
replacement = m.group(0).substring(0,m.group(0).length()-1).replaceAll("<", ";<").concat("<");
m.appendReplacement(finalXml,replacement);
}
m.appendTail(finalXml);
System.out.println(finalXml);
}
}