Search code examples
javaxml

Java xml parsing getting always null values even though xml is correctly populated


I am trying to call a xml webservice and parse its response . Below is part of response: enter image description here

As you see above, there will be multiple sections of Tag "Results". I need to loop on each result section and populate a List of Object.

Following is the code:

 public PopulateQueryDefination_Wrapper PopulateQueryDefTable(String ReqId) throws IOException, UnirestException {
        PopulateQueryDefination_Wrapper qd_wrap = new PopulateQueryDefination_Wrapper();
        List<QueryDefinationObject> listOfQueryDefination = new ArrayList<>();
        ConfigVariables con = new ConfigVariables();
        String soapEndpointUrl = con.getSOAP_Base_URI() + "Service.asmx";
        //String soapEndpointUrl = "https://shekhar.free.beeceptor.com/Service.asmx";
        System.out.println(soapEndpointUrl);
        URL url = null;
        URLConnection connection = null;
        String responseString = null;
        String outputString = "";
        OutputStream out = null;
        InputStreamReader isr = null;
        BufferedReader in = null;
        String OverallStatus = null;
        String RequestID = null;

        //Payload creation - start
        CreatePayload_QueryDefination pay_QD = new CreatePayload_QueryDefination();
        String xmlInput = "";
        if (ReqId == null) {
            xmlInput = pay_QD.GetQDPayload();//To be call for 1st run
        } else {
            xmlInput = pay_QD.GetQDPayload();//To be called for subsequent run
        }
        //Payload creation - end

        try {
            url = new URL(soapEndpointUrl);
            HttpsURLConnection httpsConn = (HttpsURLConnection) url.openConnection();

            byte[] buffer = new byte[xmlInput.length()];
            buffer = xmlInput.getBytes();

            httpsConn.setRequestProperty("Content-Length", String.valueOf(buffer.length));
            httpsConn.setRequestProperty("Content-Type", "text/xml");
            httpsConn.setRequestMethod("POST");
            httpsConn.setDoOutput(true);
            out = httpsConn.getOutputStream();
            out.write(buffer);
            out.close();

            // Read the response and write it to standard out.
            isr = new InputStreamReader(httpsConn.getInputStream());
            in = new BufferedReader(isr);

            String response1 = in.lines().collect(Collectors.joining());
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder;
            builder = factory.newDocumentBuilder();            
            StringBuilder xmlStringBuilder = new StringBuilder();
            xmlStringBuilder.append(response1);
            ByteArrayInputStream input = new ByteArrayInputStream(
                    xmlStringBuilder.toString().getBytes("UTF-8"));
            
            Document qc_document = builder.parse(input);
            qc_document.getDocumentElement().normalize();
            
            OverallStatus = qc_document.getElementsByTagName("OverallStatus").item(0).getTextContent();
            RequestID = qc_document.getElementsByTagName("RequestID").item(0).getTextContent();

            NodeList Results_Nodes = qc_document.getElementsByTagName("Results");
            
            for (int i = 0; i < Results_Nodes.getLength(); i++) {
                String CreatedDate = null;
                String ModifiedDate = null;
                String ObjectID = null;
                String CustomerKey = null;
                String Name = null;
                String QueryText = null;
                String TargetType = null;
                String TargetUpdateType = null;
                String Status = null;
                String CategoryID = null;
                Node Result = qc_document.getElementsByTagName("Results").item(i);
                
                //------------------------------
                //StringWriter buf = new StringWriter();
                //Transformer xform = TransformerFactory.newInstance().newTransformer();
                //xform.transform(new DOMSource(Result), new StreamResult(buf));
                //System.out.println(buf.toString()); // your string
                
                
                
                //-------------------------------------
                
                
                if (Result.getNodeType() == Node.ELEMENT_NODE) {
                    //Element ResultElement = (Element) Result;
                    NodeList ResultDetails = Result.getChildNodes();

                    for (int j = 0; j < ResultDetails.getLength(); j++) {
                        Node detail = ResultDetails.item(j);
                        if (detail.getNodeType() == Node.ELEMENT_NODE) {
                            Element detailElement = (Element) detail;
                            switch (detailElement.getTagName()) {
                                case "CreatedDate":
                                    CreatedDate = detailElement.getNodeValue();
                                    break;
                                case "ModifiedDate":
                                    ModifiedDate = detailElement.getNodeValue();
                                    break;
                                case "ObjectID":
                                    ObjectID = detailElement.getNodeValue();
                                    break;
                                case "CustomerKey":
                                    CustomerKey = detailElement.getNodeValue();
                                    break;
                                case "Name":
                                    Name = detailElement.getNodeValue();
                                    System.out.println("Name is - "+Name);
                                    break;
                                case "QueryText":
                                    QueryText = detailElement.getNodeValue();
                                    break;
                                case "TargetType":
                                    TargetType = detailElement.getNodeValue();
                                    break;
                                case "TargetUpdateType":
                                    TargetUpdateType = detailElement.getNodeValue();
                                    break;
                                case "Status":
                                    Status = detailElement.getNodeValue();
                                    break;
                                case "CategoryID":
                                    CategoryID = detailElement.getNodeValue();
                                    break;
                            }
                        }
                    }
                }

                QueryDefinationObject newQD = new QueryDefinationObject(Name, Status, CategoryID, CreatedDate, CustomerKey, ModifiedDate, ObjectID, TargetType, TargetUpdateType, QueryText);
                listOfQueryDefination.add(newQD);
            }
            qd_wrap.setOverallStatus(OverallStatus);
            qd_wrap.setRequestId(RequestID);
            qd_wrap.setPopQD(listOfQueryDefination);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }

        return qd_wrap;
    }

The response is coming ok. I can confirm this as i am able to get values of OveralAllStatus and RequestId properly using

OverallStatus = qc_document.getElementsByTagName("OverallStatus").item(0).getTextContent();
            RequestID = qc_document.getElementsByTagName("RequestID").item(0).getTextContent();

However when i parse the nodelist to node and then loop each child in node, i am able to get tag names , but tag values are null

if (Result.getNodeType() == Node.ELEMENT_NODE) {
                    //Element ResultElement = (Element) Result;
                    NodeList ResultDetails = Result.getChildNodes();

                    for (int j = 0; j < ResultDetails.getLength(); j++) {
                        Node detail = ResultDetails.item(j);
                        if (detail.getNodeType() == Node.ELEMENT_NODE) {
                            Element detailElement = (Element) detail;
                            switch (detailElement.getTagName()) {
                                case "CreatedDate":
                                    CreatedDate = detailElement.getNodeValue();
                                    break;
                                case "ModifiedDate":
                                    ModifiedDate = detailElement.getNodeValue();
                                    break;

In the above code Created date is always null even thought it has values in response message. Same for other fields as well

I dont know what mistake i am doing. i have check the response using tunneling between my application and server and see good response coming back.

thanks a lot

I am expecting that i get values from nodes when i loop them


Solution

  • I think your problem is that you use detailElement.getNodeValue(), instead you should use detailElement.getTextContent() like you do for the OverallStatus and RequestId.

    So just replace your switch with this:

        switch (detailElement.getTagName()) {
            case "CreatedDate":
                CreatedDate = detailElement.getTextContent();
                break;
            case "ModifiedDate":
                ModifiedDate = detailElement.getTextContent();
                break;
            case "ObjectID":
                ObjectID = detailElement.getTextContent();
                break;
            case "CustomerKey":
                CustomerKey = detailElement.getTextContent();
                break;
            case "Name":
                Name = detailElement.getTextContent();
                System.out.println("Name is - "+Name);
                break;
            case "QueryText":
                QueryText = detailElement.getTextContent();
                break;
            case "TargetType":
                TargetType = detailElement.getTextContent();
                break;
            case "TargetUpdateType":
                TargetUpdateType = detailElement.getTextContent();
                break;
            case "Status":
                Status = detailElement.getTextContent();
                break;
            case "CategoryID":
                CategoryID = detailElement.getTextContent();
                break;
        }
    

    DOMDocument getNodeValue() returns null (contains an output escaped string)