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

如何从连续流读取含/不含XML声明的XML原始字符串并拆分?

解决方案:拆分连续流中带/不带XML声明的完整XML块

针对你遇到的兼容问题——无法处理无XML声明的连续XML流拆分,结合每个XML都有固定root节点的特性,我们可以直接构造正则匹配完整的XML块,而非依赖分隔符拆分,这样就能完美覆盖所有场景。

核心思路

每个目标XML的结构无非两种:

  • 带XML声明:<?xml...?> <root>...</root>
  • 无XML声明:<root>...</root>

我们可以用一个正则直接匹配这两种结构,一次性捕获完整的XML字符串,无需拆分后拼接。

匹配正则表达式

(?:<\?xml\s+.*?\?>\s*)?<root>.*?</root>

对正则各部分的说明:

  • (?:<\?xml\s+.*?\?>\s*)?:可选的XML声明匹配。(?:...)是非捕获组(避免额外捕获无关内容),?表示该组可省略;\s+匹配声明内的空格,.*?非贪婪匹配声明内容,\s*匹配声明后的任意空白(换行、空格等)。
  • <root>.*?</root>:匹配固定的root节点,.*?非贪婪匹配内部所有内容,确保遇到第一个</root>就停止,正好对应单个XML的结束。

修改后的代码实现

try (Socket socket = server.accept()) {
    try (InputStream in = socket.getInputStream()) {
        Scanner scanner = new Scanner(new InputStreamReader(in, "UTF-8"));
        // 替换<root>为你实际的固定根节点名称
        String xmlCapturePattern = "(?:<\\?xml\\s+.*?\\?>\\s*)?<root>.*?</root>";
        List<String> completeXmlList = new ArrayList<>();
        
        String currentXml;
        // 循环捕获所有完整XML块,直到流结束
        while ((currentXml = scanner.findWithinHorizon(xmlCapturePattern, 0)) != null) {
            // 可选:去除前后空白,根据你的业务需求调整
            currentXml = currentXml.trim();
            completeXmlList.add(currentXml);
            // 调试用,可删除
            System.out.println("捕获到完整XML:\n" + currentXml);
        }
    }
}

为什么这个方案更可靠?

  • 完全兼容带/不带XML声明的场景,也支持混合输入流。
  • 直接捕获完整XML字符串,无需像原方案那样处理分隔符丢失的问题。
  • findWithinHorizon(pattern, 0)会持续扫描输入流直到找到匹配或流结束,非常适合处理Socket这类连续输入场景。

测试你的混合场景

针对你给出的混合输入:

<?xml version="1.0" standalone="yes"?> <root> </root> <?xml version="1.0" standalone="yes"?> <root> </root> <root> </root>

代码会将其拆分为3个独立的完整XML字符串:

  1. <?xml version="1.0" standalone="yes"?> <root> </root>
  2. <?xml version="1.0" standalone="yes"?> <root> </root>
  3. <root> </root>

注意事项

  • 如果你的root节点内部可能出现</root>字符串(比如文本或CDATA中),当前正则会提前终止匹配。这种情况下需要调整正则,排除CDATA和文本中的匹配,比如:
    (?:<\?xml\s+.*?\?>\s*)?<root>(?:(?!<\/root>).)*<\/root>
    
    这个版本用(?!<\/root>).确保只匹配到真正的root结束标签。
  • 务必将正则中的<root>替换为你实际业务中的固定根节点名称。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:20:58