Android XML解析报错:仅允许单个根元素,求解析含JSON的XML方案
解决XML解析报错:Only one root element allowed 并提取
内的JSON
首先,你遇到的org.w3c.dom.DOMException: Only one root element allowed错误,核心原因是XML语法强制要求必须有且仅有一个根元素,而你的响应内容直接包含<head>和<body>两个同级元素,没有外层包裹的根节点,这直接违反了XML的基本规则,导致解析器报错。
解决步骤
- 给原始XML内容包裹一个自定义根元素(比如
<response>),让它成为合法的XML结构; - 解析合法的XML,定位到
<pre>标签,提取其中的文本内容; - 将提取到的文本解析为JSON对象供业务使用。
修改后的完整代码
private void xmlParsing(String qrCode) { try { // 1. 清理无效字符并包裹根元素,修复XML合法性问题 qrCode = qrCode.replaceAll("[^\\x20-\\x7e]", ""); String validXml = "<response>" + qrCode + "</response>"; // 2. 初始化解析器并解析合法XML DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(new ByteArrayInputStream(validXml.getBytes("utf-8"))); doc.getDocumentElement().normalize(); // 3. 定位<pre>标签并提取内部的JSON文本 NodeList preList = doc.getElementsByTagName("pre"); if (preList.getLength() > 0) { Node preNode = preList.item(0); String jsonText = preNode.getTextContent().trim(); // 4. 解析JSON(这里以Gson为例,可替换为Jackson等其他库) Gson gson = new Gson(); LoginResponse response = gson.fromJson(jsonText, LoginResponse.class); // 示例:打印解析后的用户信息 Log.e("解析结果", "登录用户:" + response.getData().getUser().getName()); } } catch (Exception e) { e.printStackTrace(); } } // 对应JSON结构的实体类示例(需补充完整getter/setter) class LoginResponse { private boolean status; private String message; private Data data; // getter和setter方法 public boolean isStatus() { return status; } public void setStatus(boolean status) { this.status = status; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Data getData() { return data; } public void setData(Data data) { this.data = data; } static class Data { private User user; private String company_logo; private int client_id; private String client_secret; // getter和setter方法 public User getUser() { return user; } public void setUser(User user) { this.user = user; } public String getCompany_logo() { return company_logo; } public void setCompany_logo(String company_logo) { this.company_logo = company_logo; } public int getClient_id() { return client_id; } public void setClient_id(int client_id) { this.client_id = client_id; } public String getClient_secret() { return client_secret; } public void setClient_secret(String client_secret) { this.client_secret = client_secret; } static class User { private int id; private String name; private String email; private String user_group_id; private int company_id; private String last_login; private String last_logout; private String profile_pic; private String created_at; private String updated_at; private String sf_reference_id; private int sf_setup; // getter和setter方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } // 其他属性的getter/setter请自行补充 } } }
关键说明
- 修复XML合法性:通过
<response>标签包裹原始内容,解决了根元素唯一的核心问题; - 提取JSON文本:使用
getElementsByTagName("pre")精准定位目标标签,再通过getTextContent()获取内部的JSON字符串; - JSON解析:示例中使用Gson库,你可以根据项目依赖选择Jackson等其他JSON解析工具,记得添加对应依赖包。
内容的提问来源于stack exchange,提问作者Achin Verma




