2013-09-29 69 views
0

我很少聊天客戶端軟件使用XML文件來存儲聊天記錄,我的處理讀/寫類是:的Java存儲/讀取XML數據 - 解析異常

public class History { 

    public String filePath; 

    public History(String filePath) { 
     this.filePath = filePath; 
    } 

    public String stripNonValidXMLCharacters(String in) { 
     StringBuffer out = new StringBuffer(); // Used to hold the output. 
     char current; // Used to reference the current character. 

     if (in == null || ("".equals(in))) return ""; // vacancy test. 
     for (int i = 0; i < in .length(); i++) { 
      current = in .charAt(i); // NOTE: No IndexOutOfBoundsException caught here; it should not happen. 
      if ((current == 0x9) || 
       (current == 0xA) || 
       (current == 0xD) || 
       ((current >= 0x20) && (current <= 0xD7FF)) || 
       ((current >= 0xE000) && (current <= 0xFFFD)) || 
       ((current >= 0x10000) && (current <= 0x10FFFF))) 
       out.append(current); 
     } 
     return out.toString(); 
    } 

    public synchronized void addMessage(String from, String agentName, String msg, String time, String channel) { 
     try { 
      DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 
      org.w3c.dom.Document doc = docBuilder.parse(filePath); 

      Node data = doc.getFirstChild(); 

      org.w3c.dom.Element root = doc.createElement(channel); 
      org.w3c.dom.Element message = doc.createElement("message"); 
      org.w3c.dom.Element _sender = doc.createElement("sender"); 
      _sender.setTextContent(stripNonValidXMLCharacters(from)); 
      org.w3c.dom.Element _content = doc.createElement("content"); 
      _content.setTextContent(stripNonValidXMLCharacters(msg)); 
      org.w3c.dom.Element _recipient = doc.createElement("recipient"); 
      _recipient.setTextContent(stripNonValidXMLCharacters(agentName)); 
      org.w3c.dom.Element _time = doc.createElement("time"); 
      _time.setTextContent(stripNonValidXMLCharacters(time)); 


      message.appendChild(_sender); 
      message.appendChild(_content); 
      message.appendChild(_recipient); 
      message.appendChild(_time); 
      root.appendChild(message); 

      data.appendChild(root); 

      TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
      Transformer transformer = transformerFactory.newTransformer(); 
      DOMSource source = new DOMSource(doc); 
      StreamResult result = new StreamResult(new File(filePath)); 
      transformer.transform(source, result); 

     } catch (Exception ex) { 
      System.out.println(ex.getStackTrace()); 
      // This is being trown randomly 
     } 
    } 

    public synchronized void getHistory(String channel) { 
     try { 
      File fXmlFile = new File(filePath); 
      DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 
      org.w3c.dom.Document doc = dBuilder.parse(fXmlFile); 
      doc.getDocumentElement().normalize(); 

      NodeList nList = doc.getElementsByTagName(channel); 

      for (int temp = 0; temp < nList.getLength(); temp++) { 
       Node nNode = nList.item(temp); 
       if (nNode.getNodeType() == Node.ELEMENT_NODE) { 
        org.w3c.dom.Element eElement = (org.w3c.dom.Element) nNode; 

        if (getTagValue("sender", eElement).contains("Serv1")) { 
         printServerMsg(getTagValue("content", eElement).replace("%27", "'"), "", getTagValue("time", eElement)); 
        } else { 
         printMsg(getTagValue("content", eElement).replace("%27", "'"), getTagValue("sender", eElement), getTagValue("time", eElement)); 
        } 

       } 
      } 
     } catch (Exception ex) { 
      System.out.println("Filling Exception"); 

      // This is also being trown 
     } 
    } 

    public String getTagValue(String sTag, org.w3c.dom.Element eElement) { 
     NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes(); 
     Node nValue = (Node) nlList.item(0); 
     return nValue.getNodeValue(); 
    } 
} 

異常寫作時我得到的: `INVALID_CHARACTER_ERR:無效或非法XML字符specified.``

和讀取異常,當Filling exception 例外這裏是java.lang.NullPointerException

任何我我怎麼能保證這不會發生?問題是這樣的基本上打破了整個客戶端當前

回答

1

而不是

System.out.println("Filling Exception"); 

總是請使用

e.printStackTrace(); 

或正確的日誌框架,像log4j的,並登錄正確的錯誤:

log.error("Filling Exception", e); 

爲什麼這很重要?

,因爲這樣做,你可能會爲我們提供了完整的堆棧跟蹤...

此外,轉義字符串用作XML內容,這是明智的使用已經寫得很好,證明像在Apache commons StringEscapeUtils工具,而不是重新發明輪子

編輯

從OP的評論

哦,謝謝,我現在可以看到,誤差在getTagValue()

有對於NPE在這裏的多種可能性,但cuplrit是在這一行

NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes(); 

下可以爲空

eElement.getElementsByTagName(sTag).item(0) 

如果文檔中沒有該名稱的標籤。

the documentation

返回集合中第index項。如果index大於或等於列表中的節點數,則此返回null。

所以我重寫這樣的方法:

public String getTagValue(String sTag, org.w3c.dom.Element eElement) { 
    Node n = eElement.getElementsByTagName(sTag).item(0); 
    if(e !=null) { 
     NodeList nlList = n.getChildNodes(); 
     Node nValue = (Node) nlList.item(0); 
     if(nValue != null) { 
      return nValue.getNodeValue(); 
     } 
    } 
    return ""; // or return null; if that is more applicable to the use case 
} 

另外要注意的是現在這個返回一個空字符串,這可能會或可能不會好:它可以去那說節點被忽視不存在...

+0

哦,謝謝,我現在可以看到該錯誤是在'getTagValue()' – Alosyius

+0

而其鑄造'java.lang.NullPointerException' – Alosyius

+0

@Alosyius:檢查出來,我更新了答案 – ppeterka