【发布时间】:2017-05-02 06:36:56
【问题描述】:
有很多工具可以转义 HTML/XML 格式的值。我使用的是StringEscapeUtils.escapeXml,但它也可以转换Unicode字符(äöü) -> (äöü)。
我需要的是转义一些特定于 XML 的标签,例如 。 (我手动创建XML,不是用JAXB,请不要问为什么)。
【问题讨论】:
有很多工具可以转义 HTML/XML 格式的值。我使用的是StringEscapeUtils.escapeXml,但它也可以转换Unicode字符(äöü) -> (äöü)。
我需要的是转义一些特定于 XML 的标签,例如 。 (我手动创建XML,不是用JAXB,请不要问为什么)。
【问题讨论】:
您可以编写方法来专门转义某些 xml 字符,如下所示:
public String escapeXml(String s) {
return s.replaceAll("&", "&").replaceAll(">", ">").replaceAll("<", "<").replaceAll("\"", """).replaceAll("'", "'");
}
礼貌 - StringEscapeUtils.escapeXml is converting utf8 characters which it should not
【讨论】:
您的 StringEscapeUtil 版本是多少? 因为文档是:
请注意,大于 0x7f 的 Unicode 字符从 3.0 开始,不再转义。
所以你可能只需要更新到最新版本(当前是 3.6)
您也可以使用它:
https://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/StringEscapeUtils.html#ESCAPE_XML10
来自apache.commons.text 而不是apache.commons.lang3
【讨论】:
如前所述,Xml 值被转义,StringEscapeUtils。
最好使用标准/专有名称,而不是转义标签名称。 作为最后的手段,在生成 xml 之前转义并在解析时取消转义值。
private static final String ESC_START = "__x";
private static final String ESC_END = "_";
private final Set<Integer> toEscape = Stream.of((int)' ', 0xA, 0xD, 0xA0,
0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A,
0x205F, 0x3000).collect(Collectors.toSet());
private String escapeName(String name){
StringBuilder sb = new StringBuilder();
for(int i=0; i<name.length();i++){
char c = name.charAt(i);
if (toEscape.contains((int) c)){
sb.append(ESC_START);
sb.append(Integer.toString((int) c));
sb.append(ESC_END);
} else {
sb.append(c);
}
}
return sb.toString();
}
private final static Pattern pattern = Pattern.compile(ESC_START+"([0-9]+)"+ESC_END);
private String unescapeName(String name){
StringBuilder sb = new StringBuilder();
int i=0;
Matcher found = pattern.matcher(name);
while(found.find(i)){
sb.append(name.substring(i,found.start()));
sb.append((char)(Integer.parseInt(found.group(1))));
i = found.end();
}
sb.append(name.substring(i,name.length()));
return sb.toString();
}
【讨论】: