Jdom 1.1.1 与符号(&)处理异常问题求助
解决JDOM解析XML时移除&前后空格的问题
嘿,这个问题我在维护老Java XML解析应用时也踩过坑!老版本的JDOM(尤其是1.x系列)在处理实体附近的空白时确实有反直觉的行为,甚至CDATA都救不了——咱们来一步步解决它:
问题根源
本质上这是JDOM默认的文本归一化(Text Normalization)和实体解析逻辑导致的:
- 老版本JDOM会自动合并相邻文本节点,并且在解析实体(哪怕是未转义的
&)时,错误地吞噬掉它前后的空格; - 哪怕用CDATA包裹内容,某些旧版本的JDOM依然会对CDATA内的文本做不必要的空白压缩,完全违背了CDATA“原样保留内容”的初衷。
解决方案
根据你的场景(维护旧应用,可能不能随便大改),给你三个可行方案:
1. 优先升级JDOM版本(最省心)
JDOM 2.x系列彻底重构了文本处理逻辑,修复了大量空白和实体相关的bug,对CDATA的处理也严格遵循XML规范。如果你的应用依赖允许升级,直接把JDOM版本换成最新的2.x,这个问题大概率会自动消失。
2. 手动拼接原始文本(不升级的情况下最可靠)
如果没法升级,别用Element.getText()——这个方法会触发JDOM的归一化逻辑。取而代之,手动遍历元素的所有子节点,直接获取文本/CDATA的原始内容:
public String getUnmodifiedText(Element targetElement) { StringBuilder rawContent = new StringBuilder(); for (Content content : targetElement.getContent()) { if (content instanceof Text) { rawContent.append(((Text) content).getText()); } else if (content instanceof CDATA) { rawContent.append(((CDATA) content).getText()); } } return rawContent.toString(); }
这个方法绕过了JDOM的自动处理,完全保留原始的空格和字符。
3. 调整SAXBuilder解析配置(针对性修复)
如果不想改太多代码,可以尝试修改SAXBuilder的解析特性,禁用实体展开和空白归一化:
SAXBuilder builder = new SAXBuilder(); // 禁用外部DTD加载(避免额外问题) builder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); // 禁止自动展开实体 builder.setExpandEntities(false); // 关闭元素内容空白忽略 builder.setIgnoringElementContentWhitespace(false);
注意:这个方案的效果取决于你使用的JDOM具体版本,有些超老版本可能不支持这些配置项。
额外提醒
顺便说一句:原始XML里的Hans & Meiser其实是不符合XML规范的——&必须转义为&。如果你的应用经常处理这种不规范的XML,建议在解析前先做一次预处理转义特殊字符,或者改用更宽松的解析器,从根源避免解析异常。
内容的提问来源于stack exchange,提问作者Tony B




