You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java使用SaxParser解析XML遇<字符导致内容截断问题

Java SAXParser解析含特殊字符XML节点内容丢失问题解决

问题根因

你遇到的内容丢失不是<符号导致的解析异常,是SAX的characters回调方法设计特性导致的:
SAX解析器不保证会把一个节点的所有文本内容一次性通过characters方法返回,尤其是当节点内容里包含转义字符(比如这里的&lt;也就是<)的时候,解析器会把文本拆成多段回调:

  • 第一次回调返回转义符前的内容:Particulates,
  • 解析完转义的&lt;之后,第二次回调返回<
  • 第三次回调返回转义符后的内容: 2.5 um
    你原来的代码每次回调都直接覆盖name字段,最后就只会保留最后一段的内容。

正确实现方案

你采用的StringBuilder累加方案是SAX解析文本节点的标准解法,完整实现参考如下:

// 类中定义全局变量
private StringBuilder textBuilder = new StringBuilder();
private boolean isName = false;
private boolean isElementaryExchange = false;
private ElementaryFlowBase currentElementaryFlowBase;

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    if ("name".equals(qName)) {
        isName = true;
        // 匹配到目标节点开始,清空StringBuilder
        textBuilder.setLength(0);
    }
    // 其他节点判断逻辑,比如isElementaryExchange的赋值
}

@Override
public void characters(char[] ch, int start, int length) throws SAXException {
    if (isElementaryExchange && isName) {
        // 只做内容追加,不做赋值
        textBuilder.append(ch, start, length);
    }
}

@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
    if ("name".equals(qName) && isElementaryExchange) {
        // 节点解析结束,统一赋值
        currentElementaryFlowBase.setName(textBuilder.toString());
        isName = false;
    }
    // 其他节点结束的处理逻辑
}

注意事项

  • 不要在characters方法里直接做赋值操作,这是SAX开发的常见误区
  • 转义字符(比如&lt;、&gt;、&amp;等)会被SAX自动解析为对应的原始字符,不需要手动处理转义

内容的提问来源于stack exchange,提问作者Davide

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 22:24:09