如何将XML格式字符串转为HashMap?现有Java代码失效求排查
问题:XML转HashMap代码无法运行,求排查错误
我从接口返回结果里用substring提取了一段XML字符串,想要转成HashMap做数据对比,但写的代码跑不起来,麻烦帮忙看看哪里错了。
提取到的XML内容
title="Language Dependence" totalvotes="32"> <results> <result level="1" value="No necessary in-game text" numvotes="0" /> <result level="2" value="Some necessary text - easily memorized or small crib sheet" numvotes="7" /> <result level="3" value="Moderate in-game text - needs crib sheet or paste ups" numvotes="22" /> <result level="4" value="Extensive use of text - massive conversion needed to be playable" numvotes="2" /> <result level="5" value="Unplayable in another language" numvotes="1" /> </results> </poll>
我写的代码
Response response = RestAssured.get(api address); String code = response.asString(); String partialCode = code.substring(15967, 16535); String partialCodeAm = partialCode.replaceAll("/>", ""); String partialCodeAp = partialCodeAm.replaceAll("<", ""); String partialCodeAf = partialCodeAp.replaceAll("\"", ""); String partialCodeAd = partialCodeAf.replaceAll("results>", ""); String partialCodeAu = partialCodeAd.replaceAll(">", ""); String partialCodeAc = partialCodeAu.replaceAll("/results>", ""); String partialCodeAk = partialCodeAc.replaceAll("/", ""); String[] parts = partialCodeAk.split(","); Map<String, String> map = new HashMap<>(); for (String part : parts) { String[] voteData = part.split(":"); String level = voteData[0].trim(); String numvotes = voteData[0].trim(); map.put(level, numvotes); }
问题排查与修正方案
你的代码存在以下关键问题:
- 硬编码截取位置:
substring(15967, 16535)完全依赖接口返回内容的固定长度,一旦接口返回内容有任何变化(比如空格增减、字段调整),截取结果直接失效,稳定性极差。 - 字符串替换逻辑混乱:一系列
replace操作彻底破坏了XML的结构,最终得到的字符串没有有效分隔符,无法用,分割出目标数据。 - 分割与赋值错误:
- 替换后的字符串中没有逗号,
parts数组只会有一个元素,后续循环完全无效。 - 循环里把
voteData[0]同时赋值给level和numvotes,就算分割成功,也会把同一个值存为键和值,完全不符合level对应numvotes的需求。
- 替换后的字符串中没有逗号,
推荐实现:用XML解析库处理(规范且稳定)
手动字符串替换解析XML极易出错,建议用专门的XML解析库(比如Jackson、RestAssured自带的XML支持)处理,以下是基于Jackson的修正代码:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import io.restassured.RestAssured; import io.restassured.response.Response; import java.util.HashMap; import java.util.List; import java.util.Map; public class XmlToMapDemo { public static void main(String[] args) { Response response = RestAssured.get("api address"); XmlMapper xmlMapper = new XmlMapper(); try { // 解析XML为Map结构 Map<String, Object> pollMap = xmlMapper.readValue(response.asString(), Map.class); // 提取results下的result列表 List<Map<String, String>> resultList = (List<Map<String, String>>) pollMap.get("results"); // 构建level到numvotes的HashMap Map<String, String> levelVoteMap = new HashMap<>(); for (Map<String, String> result : resultList) { levelVoteMap.put(result.get("level"), result.get("numvotes")); } // 验证结果 System.out.println(levelVoteMap); } catch (Exception e) { e.printStackTrace(); } } }
若坚持手动处理(不推荐),可调整字符串逻辑:
Response response = RestAssured.get("api address"); String code = response.asString(); // 动态截取<results>到</results>的内容,替代硬编码位置 int startIdx = code.indexOf("<results>"); int endIdx = code.indexOf("</results>") + "</results>".length(); String partialCode = code.substring(startIdx, endIdx); // 按<result分割,跳过第一个空元素 String[] resultParts = partialCode.split("<result"); Map<String, String> levelVoteMap = new HashMap<>(); for (int i = 1; i < resultParts.length; i++) { String part = resultParts[i]; // 提取level值 int levelStart = part.indexOf("level=\"") + 7; int levelEnd = part.indexOf("\"", levelStart); String level = part.substring(levelStart, levelEnd); // 提取numvotes值 int voteStart = part.indexOf("numvotes=\"") + 10; int voteEnd = part.indexOf("\"", voteStart); String numvotes = part.substring(voteStart, voteEnd); levelVoteMap.put(level, numvotes); } // 验证结果 System.out.println(levelVoteMap);
内容的提问来源于stack exchange,提问作者Mari Jeparska
相关产品推荐
相关产品推荐

