Android Studio中使用Java解析XML格式字符串数据的方法
问题根源
原有解析逻辑是匹配employee子节点、读取子节点文本内容,但你拿到的目标XML结构里,根节点就是<DeviceInfo>,需要提取的dc/dpId/mc/mi/rdsId/rdsVer全是该节点的属性,不是嵌套子节点,因此原有逻辑完全无法匹配到目标内容。
另外你代码开头硬编码XML字符串的位置,内部双引号没有做转义,会直接触发编译错误,字符串内部的双引号需要加反斜杠转义为\"。
修正后的DOM解析实现
直接替换原有try块中匹配employee节点的错误逻辑即可,同时建议关闭DOM解析的外部实体加载,既提升解析速度,也避免XML注入风险:
// 硬编码字符串转义修正示例 String DeviceInfo= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><DeviceInfo dc=\"\" dpId=\"\" mc=\"\" mi=\"\" rdsId=\"\" rdsVer=\"\"/>"; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { Bundle b = data.getExtras(); if (b != null) { String deviceInfo = b.getString("DEVICE_INFO", ""); String pidData = b.getString("PID_DATA"); String dnc = b.getString("DNC", ""); String dnr = b.getString("DNR", ""); String rdServiceInfo = b.getString("RD_SERVICE_INFO", ""); Log.d("device ", "" + deviceInfo); // 解析结果存储变量 String dc = ""; String dpId = ""; String mc = ""; String mi = ""; String rdsId = ""; String rdsVer = ""; try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // 关闭外部实体加载,提升速度同时规避安全风险 dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); DocumentBuilder db = dbf.newDocumentBuilder(); InputSource is = new InputSource(); is.setCharacterStream(new StringReader(deviceInfo)); Document doc = db.parse(is); // 定位DeviceInfo节点 NodeList deviceNodes = doc.getElementsByTagName("DeviceInfo"); if (deviceNodes.getLength() > 0) { Element deviceElement = (Element) deviceNodes.item(0); // 直接读取节点属性 dc = deviceElement.getAttribute("dc"); dpId = deviceElement.getAttribute("dpId"); mc = deviceElement.getAttribute("mc"); mi = deviceElement.getAttribute("mi"); rdsId = deviceElement.getAttribute("rdsId"); rdsVer = deviceElement.getAttribute("rdsVer"); // 日志验证取值结果 Log.d("Device解析结果", String.format("dc=%s, dpId=%s, mc=%s, mi=%s, rdsId=%s, rdsVer=%s", dc, dpId, mc, mi, rdsId, rdsVer)); } } catch (Exception e) { e.printStackTrace(); } text1.setText(pidData); text.setText(deviceInfo); } } }
轻量替代方案(XmlPullParser)
如果追求更低内存占用,可以用Android原生内置的XmlPullParser实现,不需要引入任何第三方依赖,解析短XML效率更高:
- 解析逻辑不需要加载整个XML文档到内存,找到目标节点后可以直接终止解析
- 系统内置API,不需要额外适配版本
核心解析代码如下:
try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(new StringReader(deviceInfo)); int eventType = parser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG && "DeviceInfo".equals(parser.getName())) { dc = parser.getAttributeValue("", "dc"); dpId = parser.getAttributeValue("", "dpId"); mc = parser.getAttributeValue("", "mc"); mi = parser.getAttributeValue("", "mi"); rdsId = parser.getAttributeValue("", "rdsId"); rdsVer = parser.getAttributeValue("", "rdsVer"); break; // 拿到目标属性直接退出循环,不需要继续解析 } eventType = parser.next(); } } catch (Exception e) { e.printStackTrace(); }
内容的提问来源于stack exchange,提问作者Suraj D
相关产品推荐
相关产品推荐

