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

如何使用Stack数据结构逐段解析XML文件并校验标签合法性

报错原因排查
  • 核心报错触发原因:Config类的循环逻辑中,单次循环内多次调用nextLine()方法,hasNextLine()仅在循环开始前校验一次存在行,后续多次调用nextLine()会消耗掉所有行内容,无剩余行时就会抛出NoSuchElementException。
  • 逻辑设计错误1:XML所有内容都在同一行,按行读取的整段内容无法直接和单个标签匹配,判断条件永远不会命中。
  • 逻辑设计错误2:字符串相等判断使用==而非equals()方法,Java中==对比字符串对象内存地址,而非内容值,即使内容匹配也会返回false。
  • 逻辑设计错误3:未区分开始标签、结束标签,直接else就执行pop(),没有校验栈是否为空就弹出,遇到非法标签时会触发空栈异常。
  • 冗余问题:Config构造方法传入的文件名参数没有被使用,内部硬编码了文件路径。
修正后实现方案

实现逻辑

  1. 一次性读取XML文件的全部内容
  2. 提取所有<>包裹的标签,区分开始标签(不带/)和结束标签(带/)
  3. 遇到开始标签压入栈,遇到结束标签时校验栈顶是否为对应的开始标签,匹配则弹出
  4. 全部标签处理完成后栈为空则输出valid,否则为invalid

修正后代码

Config类

import java.util.HashMap;
import java.util.Stack;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Config {
    HashMap<String, String> obj = new HashMap<>();
    Stack<String> tagStack = new Stack<>();
    // 匹配XML标签的正则
    private static final Pattern TAG_PATTERN = Pattern.compile("<[^>]+>");

    public Config(String name) {
        try {
            File xmlFile = new File(name);
            Scanner reader = new Scanner(xmlFile);
            // 读取全部XML内容
            StringBuilder xmlContent = new StringBuilder();
            while (reader.hasNextLine()) {
                xmlContent.append(reader.nextLine());
            }
            reader.close();

            // 提取所有标签
            Matcher matcher = TAG_PATTERN.matcher(xmlContent.toString());
            boolean isValid = true;

            while (matcher.find()) {
                String tag = matcher.group();
                // 判断是否是结束标签
                if (tag.startsWith("</")) {
                    String startTag = tag.replace("/", "");
                    // 栈为空或者栈顶不匹配则非法
                    if (tagStack.isEmpty() || !tagStack.peek().equals(startTag)) {
                        isValid = false;
                        break;
                    }
                    tagStack.pop();
                } else {
                    // 开始标签压入栈
                    tagStack.push(tag);
                }
            }

            // 全部处理完成后栈为空且过程无异常则合法
            if (isValid && tagStack.isEmpty()) {
                System.out.println("valid");
            } else {
                System.out.println("invalid");
            }

        } catch (FileNotFoundException e) {
            System.out.println("An error occurred.");
            e.printStackTrace();
        }
    }
}

Main类(仅修正冗余逻辑,原有读取atm.log的逻辑保留)

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws Exception {
        try {
            File logFile = new File("atm.log");
            Scanner logReader = new Scanner(logFile);
            while (logReader.hasNextLine()) {
                String data = logReader.nextLine();
                System.out.println(data);
            }
            logReader.close();
        } catch (FileNotFoundException e) {
            System.out.println("An error occurred when reading atm.log.");
            e.printStackTrace();
        }
        String xmlName = "atm.xml";
        Config info = new Config(xmlName);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:09:05