Skip to content
Advertisement

Return a value present from recursive function in Java

I am trying to extract a value from a while loop. In the output, I am able to capture the value in the Else statement but not able to return it when it is in the console log from the main statement. I want to be able to return “103” when I call the getValueFromkey() function.

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Iterator;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.XML;

public class Tesst {
    
static String line = "", str = "";
    
    public static void main(String[] args) throws Exception {

        String filepath = "C:/Users/Navi/Downloads/sample.xml";
        
        BufferedReader br = new BufferedReader(new FileReader(filepath));
        while ((line = br.readLine()) != null) {
            str += line;
        }
        
        br.close();

        JSONObject jsondata = XML.toJSONObject(str);
        
        System.out.println("From main: " + getValueFromKey(jsondata, "routing_bic"));
    }

    private static Integer getValueFromKey(JSONObject json, String key) {
        boolean exists = json.has(key);
        Iterator<?> keys;
        String nextKeys;
        Integer foundKey = 0;

        if(!exists) {
            keys = json.keys();
            while (keys.hasNext()) {
                // Store next Key in nextKeys
                nextKeys = (String)keys.next();
                
                try {
                    // Check if the given Key is a JSON Object
                    if(json.get(nextKeys) instanceof JSONObject) {
                        // If Key does not exist
                        if(!exists) {
                            // Recursive function call
                            getValueFromKey(json.getJSONObject(nextKeys), key);
                        }
                    } else if (json.get(nextKeys) instanceof JSONArray) {
                        JSONArray jsonArray = json.getJSONArray(nextKeys);
                        for(int i = 0; i < jsonArray.length(); i++) {
                            String jsonArrayString = jsonArray.get(i).toString();
                            JSONObject innerJsonObject = new JSONObject(jsonArrayString);
                            
                            // Recursive function call
                            if(!exists) {
                                getValueFromKey(innerJsonObject.getJSONObject(nextKeys), key);
                            }
                        }
                    }
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        } else {
            // If key exists, print value
            foundKey += parseObject(json, key);
            System.out.println("From loop: " + foundKey);
            return foundKey;
        }
//      System.out.println("Found Key = " + foundKey);
        return 1; // Return 1 when key not found
    }
    
    private static Integer parseObject(JSONObject json, String key) {
        System.out.println("From parseObject = " + json.get(key));
        return (Integer) json.get(key);
    }
    
}

Sample XML

<Test>
    <BIBRq>
        <UserId>123</UserId>
        <CIFNo>123</CIFNo>
        <CompanyId>asd</CompanyId>
        <LegalId>123</LegalId>
        <LegalIdType>ABC</LegalIdType>
        <LegalIdCountry>ABC</LegalIdCountry>
    </BIBRq>
    <SubSvcRq>
        <SubSvc>
            <SubSvcRqHeader>
                <SvcCode>ABCD</SvcCode>
                <SubSvcSeq>1</SubSvcSeq>
                <TxnRef>12345</TxnRef>
                <ClientUserID/>
            </SubSvcRqHeader>
            <SubSvcRqDetail>
                <ft_tnx_record>
                    <additional_field>
                        <account_details>
                            <routing_bic>103</routing_bic>
                        </account_details>
                    </additional_field>
                </ft_tnx_record>
            </SubSvcRqDetail>
        </SubSvc>
    </SubSvcRq>
</Test>

Output:

From parseObject = 103

From loop: 103

From main: 1

Advertisement

Answer

There are two errors in your code.

  1. I notice that you recursively call the function getValueFromKey. That will never work if you don’t assign the variable foundKey with the return value of the recursive invocation.
    So, just change each recursive calls in this:

    foundKey = getValueFromKey(…, key);

  2. In addition, the last statement return 1 is wrong, because it will override any possible value returned by the subsequent recursive invocation. So, in replacement, you have to return always the foundKey variable.

I slightly changed your code and tested it with your sample file and it works fine. Differently than yours, I also wrapped the BufferedReader with try-with-resouce block, which I always prefer to simple try-catch, because it garantees that it closes the stream for you, even in case of exceptions.

Here is the code:

import java.io.BufferedReader;
import java.io.FileReader;

import java.util.Iterator;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.XML;

public class Test {
    
    static String line = "", str = "";
    
    public static void main(String[] args) throws Exception {

        String filepath = "C:\Users\marco\Downloads\sample.xml";
        
        try ( BufferedReader br = new BufferedReader(new FileReader(filepath)); ) {
            while ((line = br.readLine()) != null) {
                str += line;
            }
        }

        JSONObject jsondata = XML.toJSONObject(str);
        
        System.out.println("From main: " + getValueFromKey(jsondata, "routing_bic"));
    }

    private static Integer getValueFromKey(JSONObject json, String key) {
        boolean exists = json.has(key);
        Iterator<?> keys;
        String nextKeys;
        Integer foundKey = 0;

        if(!exists) {
            keys = json.keys();
            while (keys.hasNext()) {
                // Store next Key in nextKeys
                nextKeys = (String)keys.next();
                
                try {
                    // Check if the given Key is a JSON Object
                    if(json.get(nextKeys) instanceof JSONObject) {
                        // If Key does not exist
                        if(!exists) {
                            // Recursive function call
                            foundKey = getValueFromKey(json.getJSONObject(nextKeys), key);
                        }
                    } else if (json.get(nextKeys) instanceof JSONArray) {
                        JSONArray jsonArray = json.getJSONArray(nextKeys);
                        for(int i = 0; i < jsonArray.length(); i++) {
                            String jsonArrayString = jsonArray.get(i).toString();
                            JSONObject innerJsonObject = new JSONObject(jsonArrayString);
                            
                            // Recursive function call
                            if(!exists) {
                                foundKey = getValueFromKey(innerJsonObject.getJSONObject(nextKeys), key);
                            }
                        }
                    }
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        } else {
            // If key exists, print value
            foundKey += parseObject(json, key);
            System.out.println("From loop: " + foundKey);
        }
//      System.out.println("Found Key = " + foundKey);
        return foundKey; // Return 1 when key not found
    }
    
    private static Integer parseObject(JSONObject json, String key) {
        System.out.println("From parseObject = " + json.get(key));
        return (Integer) json.get(key);
    }
    
}

And here is the output:

From parseObject = 103
From loop: 103
From main: 103
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement