You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动