Java使用SAXParser解析嵌套XML元素取值为null如何解决
问题根因
你当前的代码逻辑存在层级判断错误:SAXParser的startElement方法每次触发仅对应当前正在解析的单个XML元素,当你进入qName.equalsIgnoreCase("den")的判断分支时,当前元素必然是den节点,此时qName不可能等于od或do,所以嵌套的判断条件永远不会触发。同时你没有记录当前解析到的星期标识的状态,等后续解析到od/do节点时,无法判断这个时间属于周几。
解决办法
按以下逻辑调整代码即可:
- 新增成员变量保存当前正在解析的星期名称,以及
od/do节点的解析状态标记 - 在
startElement中分别处理不同节点的状态赋值 - 在
characters方法中根据状态标记和当前星期,把时间值赋值给对应属性 - 节点解析完成后重置状态标记,避免值污染
调整后的startElement代码示例
// 提前声明需要的成员变量 private String currentDay; // 存储当前解析的星期名称 private boolean b_od, b_do; // 标记当前是否在解析od/do节点 private Otwarte otwarte; // 你原有其他业务变量保留即可 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("OTEV_DOBY")) { otwarte = new Otwarte(); } else if (qName.equalsIgnoreCase("den")) { // 解析到den节点时,记录当前的星期名称 currentDay = attributes.getValue("name"); } else if (qName.equalsIgnoreCase("od")) { // 标记当前正在解析开门时间 b_od = true; } else if (qName.equalsIgnoreCase("do")) { // 标记当前正在解析关门时间 b_do = true; } }
characters方法示例
@Override public void characters(char[] ch, int start, int length) throws SAXException { String value = new String(ch, start, length).trim(); if (value.isEmpty()) return; if (b_od) { // 根据当前星期给对应开门时间属性赋值 if (currentDay.equalsIgnoreCase("Pondělí")) { otwarte.setPn_od(value); } else if (currentDay.equalsIgnoreCase("Úterý")) { otwarte.setWt_od(value); } else if (currentDay.equalsIgnoreCase("Středa")) { otwarte.setSr_od(value); } else if (currentDay.equalsIgnoreCase("Čtvrtek")) { otwarte.setCz_od(value); } else if (currentDay.equalsIgnoreCase("Pátek")) { otwarte.setPt_od(value); } else if (currentDay.equalsIgnoreCase("Sobota")) { otwarte.setSob_od(value); } else if (currentDay.equalsIgnoreCase("Neděle")) { otwarte.setNd_od(value); } // 赋值完成重置状态 b_od = false; } else if (b_do) { // 根据当前星期给对应关门时间属性赋值 if (currentDay.equalsIgnoreCase("Pondělí")) { otwarte.setPn_do(value); } else if (currentDay.equalsIgnoreCase("Úterý")) { otwarte.setWt_do(value); } else if (currentDay.equalsIgnoreCase("Středa")) { otwarte.setSr_do(value); } else if (currentDay.equalsIgnoreCase("Čtvrtek")) { otwarte.setCz_do(value); } else if (currentDay.equalsIgnoreCase("Pátek")) { otwarte.setPt_do(value); } else if (currentDay.equalsIgnoreCase("Sobota")) { otwarte.setSob_do(value); } else if (currentDay.equalsIgnoreCase("Neděle")) { otwarte.setNd_do(value); } // 赋值完成重置状态 b_do = false; } }
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

