Java解析含多节点XML遇空指针异常,求解决方案
XML解析空指针异常及数据获取问题
我在解析包含多节点的XML时,执行System.out.println("Revenue Value : " + element.getElementsByTagName("ISREVENUE").item(0).getTextContent());抛出空指针异常,同时无法正确获取GROUP节点的NAME属性、ISREVENUE和MASTERID子标签的值。期望输出每个GROUP节点的名称、ISREVENUE值、MASTERID值,示例如下:
Name (Group) : "Administration Expenses" Revenue Value : "Yes" MasterID Value : 166
XML内容
<ENVELOPE> <HEADER> <VERSION>1</VERSION> <STATUS>1</STATUS> </HEADER> <BODY> <DESC> <CMPINFO> <EXCISEDUTYCLASSIFICATION>0</EXCISEDUTYCLASSIFICATION> <SERIALNUMBER>0</SERIALNUMBER> <ADJUSTMENTCLASSIFICATION>0</ADJUSTMENTCLASSIFICATION> <INCOMETAXSLAB>0</INCOMETAXSLAB> <INCOMETAXCLASSIFICATION>0</INCOMETAXCLASSIFICATION> <LBTCLASSIFICATION>0</LBTCLASSIFICATION> <TAXUNIT>0</TAXUNIT> <RETURNMASTER>0</RETURNMASTER> <VOUCHER>0</VOUCHER> </CMPINFO> </DESC> <DATA> <COLLECTION ISMSTDEPTYPE="Yes" MSTDEPTYPE="4"> <GROUP NAME="Administration Expenses" RESERVEDNAME=""> <ISDELETED TYPE="Logical"></ISDELETED> <ISREVENUE TYPE="Logical">Yes</ISREVENUE> <ISDEEMEDPOSITIVE TYPE="Logical">Yes</ISDEEMEDPOSITIVE> <MASTERID TYPE="Number"> 166</MASTERID> </GROUP> <GROUP NAME="Bank Accounts" RESERVEDNAME="Bank Accounts"> <ISDELETED TYPE="Logical"></ISDELETED> <ISREVENUE TYPE="Logical">No</ISREVENUE> <ISDEEMEDPOSITIVE TYPE="Logical">Yes</ISDEEMEDPOSITIVE> <MASTERID TYPE="Number"> 22</MASTERID> </GROUP> <GROUP NAME="Bank OD A/c" RESERVEDNAME="Bank OD A/c"> <ISDELETED TYPE="Logical"></ISDELETED> <ISREVENUE TYPE="Logical">No</ISREVENUE> <ISDEEMEDPOSITIVE TYPE="Logical">No</ISDEEMEDPOSITIVE> <MASTERID TYPE="Number"> 11</MASTERID> </GROUP> </COLLECTION> </DATA> </BODY> </ENVELOPE>
出错的Java代码
try { File xmlFile = new File("C:/Srinivas/NewData.xml"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = (Document) builder.parse(xmlFile); NodeList nodeList = doc.getElementsByTagName("GROUP"); for (int itr = 0; itr < nodeList.getLength(); itr++) { Node node = nodeList.item(itr); if (node.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) node; String name = element.getAttribute("Name"); System.out.println("Revenue Value : " + element.getElementsByTagName("ISREVENUE").item(0).getTextContent()); System.out.println("Deemed Value : " + element.getElementsByTagName("ISDEEMEDPOSITIVE").item(0).getTextContent()); } } System.out.println("completed"); } catch (Exception ex) { System.out.println(ex.getMessage()); }
问题原因及修复方案
问题1:属性名大小写不匹配
XML中GROUP节点的属性是NAME(全大写),但代码中用element.getAttribute("Name")(首字母大写其余小写),导致获取不到属性值,返回空字符串。
问题2:空指针异常隐患
调用item(0)后直接调用getTextContent(),如果目标标签不存在会触发空指针异常,必须先判断节点是否为空。
修复后的代码
try { File xmlFile = new File("C:/Srinivas/NewData.xml"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(xmlFile); NodeList nodeList = doc.getElementsByTagName("GROUP"); for (int itr = 0; itr < nodeList.getLength(); itr++) { Node node = nodeList.item(itr); if (node.getNodeType() == Node.ELEMENT_NODE) { Element groupElement = (Element) node; // 修正属性名大小写,匹配XML中的NAME String groupName = groupElement.getAttribute("NAME"); System.out.println("Name (Group) : \"" + groupName + "\""); // 获取ISREVENUE节点并做非空判断 Node isRevenueNode = groupElement.getElementsByTagName("ISREVENUE").item(0); String revenueValue = isRevenueNode != null ? isRevenueNode.getTextContent().trim() : "N/A"; System.out.println("Revenue Value : \"" + revenueValue + "\""); // 获取MASTERID节点并做非空判断,去除值中的空格 Node masterIdNode = groupElement.getElementsByTagName("MASTERID").item(0); String masterIdValue = masterIdNode != null ? masterIdNode.getTextContent().trim() : "N/A"; System.out.println("MasterID Value : " + masterIdValue); System.out.println(); // 分隔每个GROUP的输出 } } System.out.println("completed"); } catch (Exception ex) { ex.printStackTrace(); }
修复说明
- 属性名修正:将
element.getAttribute("Name")改为groupElement.getAttribute("NAME"),严格匹配XML中属性的大小写。 - 空指针防护:获取子节点后先判断是否为
null,再调用getTextContent(),避免空指针异常。 - 格式化输出:按照期望的格式输出,添加
trim()去除MASTERID值中的多余空格。 - 异常处理优化:改用
ex.printStackTrace()打印完整异常栈,便于排查深层问题。
内容的提问来源于stack exchange,提问作者SB3279
相关产品推荐
相关产品推荐

