[英]Parsing XML using java DOM
我是Java新手,我有一個任務是使用http和當前網址解析一個xml文件http://belbooner.site40.net/testXmls/details.xml
我創建了一些使用Dom方法解析它的類,但是在嘗試獲取一個Nodes值時我有java.lang.NullPointerException所以這里是代碼
import java.security.KeyStore.Builder;
import java.util.*;
import java.io.*;
import java.net.*;
import javax.swing.text.Document;
import javax.xml.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.w3c.dom.*;
import org.w3c.dom.CharacterData;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class RequestResponse {
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
URL url = new URL("http://belbooner.site40.net/testXmls/details.xml");
RequestResponse req= new RequestResponse();
req.getHTTPXml(url);
}
void getHTTPXml(URL url) throws ParserConfigurationException, IOException, SAXException {
//URL url = new URL("http://belbooner.site40.net/testXmls/details.xml");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("ACCEPT","application/xml");
InputStream xml = conn.getInputStream();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document document = builder.parse(xml);
System.out.println(document);
String doctype = conn.getContentType();
System.out.print(doctype);
NodeList root = document.getChildNodes();
Node server = getNodes("server",root);
Node check = getNodes("check", server.getChildNodes());
NodeList nodes = check.getChildNodes();
String checkid= getNodeValue("checkid", nodes);
System.out.println(checkid);
conn.disconnect();
//return (Document) DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xml);
}
Node getNodes(String tagName, NodeList nodes) {
for(int i=0; i< nodes.getLength();i++) {
Node node= nodes.item(i);
if(node.getNodeName().equalsIgnoreCase(tagName)) {
return node;
}
}
return null;
}
String getNodeValue(String tagName, NodeList nodes ) {
for ( int i = 0; i < nodes.getLength(); i++ ) {
Node node = nodes.item(i);
if (node.getNodeName().equalsIgnoreCase(tagName)) {
NodeList childNodes = node.getChildNodes();
for (int y = 0; y < childNodes.getLength(); y++ ) {
Node data = childNodes.item(y);
if ( data.getNodeType() == Node.TEXT_NODE ) {
return data.getNodeValue();
}
if(data instanceof CharacterData) {
CharacterData cd= (CharacterData) data;
return cd.getData();
}
}
}
}
return "";
}
}
我得到的堆棧跟蹤如下:
application/xmlException in thread "main" java.lang.NullPointerException at
RequestResponse.getHTTPXml(RequestResponse.java:45) at
RequestResponse.main(RequestResponse.java:22)
changin Node server = getNodes("server",root);
到`
Node resultNode = getNodes("result", root);
Node server = getNodes("server", resultNode.getChildNodes());`
`application/xmlException in thread "main" java.lang.NullPointerException
at RequestResponse.getHTTPXml(RequestResponse.java:49)
at RequestResponse.main(RequestResponse.java:22)
`
請幫我找到問題。
問題是Node server = getNodes("server",root);
返回null。
為什么會這樣? 那你看看你是如何實現getNodes的
Node getNodes(String tagName, NodeList nodes) {
for(int i=0; i< nodes.getLength();i++) {
Node node= nodes.item(i);
if(node.getNodeName().equalsIgnoreCase(tagName)) {
return node;
}
}
return null;
}
您將文檔根目錄作為單個“結果”節點作為輸入,您遍歷它並比較節點的名稱是否在這種情況下“服務器”,這將永遠不會,因此您返回null並獲得NPE。
您的節點查找必須以下列方式完成:
NodeList root = document.getChildNodes();
// Keep in mind that you have the following structure:
// result
// server
// checks
// check
// checkId
// check
// checkId
Node resultNode = getNodes("result", root);
Node server = getNodes("server", resultNode.getChildNodes());
Node checks = getNodes("checks", server.getChildNodes());
NodeList childNodes = checks.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node possibleCheck = childNodes.item(i);
if (possibleCheck.getNodeName().equals("check")) {
String checkid = getNodeValue("checkid", possibleCheck.getChildNodes());
System.out.println(checkid);
}
}
這樣您就可以遍歷正確的節點列表。
在解析xml時,使用XPath更有效,更靈活(比正常迭代)。
IBM的XPath教程
XPath參考Orielly教程
Xpath參考Oracle java教程
試試下面的代碼。
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class RequestResponse {
public static void main(String[] args) throws ParserConfigurationException,
IOException, SAXException {
URL url = new URL("http://belbooner.site40.net/testXmls/details.xml");
RequestResponse req = new RequestResponse();
req.getHTTPXml(url);
}
void getHTTPXml(URL url) throws ParserConfigurationException, IOException,
SAXException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("ACCEPT", "application/xml");
InputStream xml = conn.getInputStream();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document document = builder.parse(xml);
System.out.println(document);
String doctype = conn.getContentType();
System.out.println(doctype);
XPathFactory pathFactory = XPathFactory.newInstance();
XPath path = pathFactory.newXPath();
XPathExpression expression;
try {
expression = path.compile("/result/server/checks/check/checkid");
NodeList nodeList = (NodeList) expression.evaluate(document,
XPathConstants.NODESET);
String checkids[] = getNodeValue(nodeList);
for (String checkid : checkids) {
System.out.print(checkid + ", ");
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
conn.disconnect();
}
String[] getNodeValue(NodeList nodes) {
String checkIds[] = new String[nodes.getLength()];
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
checkIds[i] = node.getTextContent();
}
return checkIds;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.