4

我是 Java 新手,我的任务是使用 http 和当前 url http://belbooner.site40.net/testXmls/details.xml解析一个 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)

改成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)

`

请帮我找出问题所在。

4

2 回答 2

3

问题是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);
    }
}

这样,您将遍历正确的节点列表。

于 2012-11-30T08:44:33.650 回答
2

在解析 xml 时,使用 XPath 更高效、更灵活(比正常迭代)。

XPath Tutorial from IBM
XPath Reference Orielly tutorial
Xpath Reference Oracle java tutorial

试试下面的代码。

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;
    }

} 
于 2012-11-30T09:10:47.410 回答