gpt4 book ai didi

Java从XML保存/读取数据——解析异常

转载 作者:行者123 更新时间:2023-12-01 14:04:04 25 4
gpt4 key购买 nike

我的小聊天客户端软件使用 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 字符。``

并且在读取异常时填充异常这里的异常是java.lang.NullPointerException

我有什么想法可以保证这种情况不会发生吗?问题是这基本上破坏了整个客户端目前

最佳答案

而不是

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

始终使用其中之一

e.printStackTrace();

或者一个适当的日志框架,如 log4j,并正确记录错误:

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

为什么这很重要?

因为通过这样做,您可以为我们提供完整的堆栈跟踪......

此外,为了转义字符串以用作 XML 内容,明智的做法是使用已经编写良好且经过验证的实用程序,例如 Apache commons StringEscapeUtils而不是重新发明轮子

编辑

摘自OP评论

Oh thanks, i can now see that the error is in getTagValue()

这里NPE有多种可能性,但cuplrit就在这一行

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

以下内容可以为空

eElement.getElementsByTagName(sTag).item(0)

如果文档中没有该名称的标签。

来自the documentation :

Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns 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
}

还要注意,现在这会返回一个空字符串,这可能会好也可能不好:它可能会被忽视,所述节点不存在......

关于Java从XML保存/读取数据——解析异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19078566/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com