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

XML结束标签解析异常求助:StringIndexOutOfBoundsException排查

解析XML时的StringIndexOutOfBoundsException问题

问题场景

要解析的XML单行内容如下:

<Index>1</Index><Price>$18.38</Price><Product>Takis Fuego, 1 Ounce (46 Pack)</Product><SoldBy> Sam's Club</SoldBy><href>https://www.google.com/shopping/product/14559077146163012667?hl=en&sxsrf=ALiCzsb1Gfl32-pXt32h0QkkE-T57FtdxA:1670964406762&psb=1&q=takis&prds=eto:15330784880350744537_0,pid:15387764403936018691,rsk:PC_15179594788466925291&sa=X&ved=0ahUKEwjPgJuOvsj-AhUJGlkFHSQsBpcQ8gIIpgooAA</href>

运行解析代码时触发以下异常:

java.lang.StringIndexOutOfBoundsException: begin 6, end -1, length 355
    at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4601)
    at java.base/java.lang.String.substring(String.java:2704)
    at SeerWebCrawler.buildGUIFile(SeerWebCrawler.java:133)
    at SeerWebCrawler.main(SeerWebCrawler.java:58)

相关代码

解析XML的代码

private static void buildGUIFile() throws IOException {
        
    List<String> fileLines = Files.readAllLines(fileName);
    for (int i = 0; i < (fileLines.size()); i++) {
        resNum = i + 1;
        int beginIndex = fileLines.indexOf("<Price>");
        int endIndex = fileLines.indexOf("</Price>");
        try {
            price = fileLines.get(i).trim().substring(fileLines.indexOf("<Price>".trim()) + "<Price>".trim().length(), fileLines.indexOf("</Price>".trim()));
        } catch (StringIndexOutOfBoundsException e) {
            System.out.println("endIndex" + endIndex);
            e.printStackTrace();
        }
    }
}

生成XML格式的代码

public String xmlString() {
    String str = "<Index>" + resultNum + "</Index>" + "<Price>" + Price + "</Price>" + "<Product>" + Product
            + "</Product>" + "<SoldBy> " + Company + "</SoldBy>" + "<href>" + link + "</href>";
    return str;
}

问题原因

异常里的end -1直接暴露了核心问题:

  1. 混淆List与String的indexOf方法:你调用的fileLines.indexOf("<Price>")是在List<String>中查找**完整等于"
    return (<Price>"的元素索引**,而非在当前循环的行字符串中查找子串位置。由于你的XML是单行完整结构,List中不存在单独的"<Price>"或"</Price>)
    "元素,因此fileLines.indexOf("</Price>")返回-1。
  2. substring参数非法:当把-1作为结束索引传入substring时,必然触发StringIndexOutOfBoundsException,因为结束索引不能小于开始索引。

修复方案

将所有索引查找操作切换到当前行的字符串上,而非整个List:

private static void buildGUIFile() throws IOException {
    List<String> fileLines = Files.readAllLines(fileName);
    for (int i = 0; i < fileLines.size(); i++) {
        resNum = i + 1;
        String currentLine = fileLines.get(i).trim();
        int beginIndex = currentLine.indexOf("<Price>");
        int endIndex = currentLine.indexOf("</Price>");
        try {
            // 先检查标签有效性,避免无效索引
            if (beginIndex != -1 && endIndex != -1 && endIndex > beginIndex) {
                price = currentLine.substring(beginIndex + "<Price>".length(), endIndex);
            } else {
                price = "N/A";
                System.out.println("Line " + resNum + ": 未找到有效的Price标签");
            }
        } catch (StringIndexOutOfBoundsException e) {
            System.out.println("endIndex: " + endIndex);
            e.printStackTrace();
        }
    }
}

额外建议

字符串截取解析XML的方式非常脆弱,一旦XML格式出现微小变化(比如标签间换行、标签内加空格)就会失效。推荐使用标准XML解析库,比如轻量易用的jsoup:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.parser.Parser;

// ...

String currentLine = fileLines.get(i).trim();
// 用XML解析器解析单行内容
Document doc = Jsoup.parse(currentLine, "", Parser.xmlParser());
// 直接获取Price标签的文本内容
price = doc.selectFirst("Price").text();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:47:51