Basically as it stands the component is still not useful for real world scenarios where JSON data is mostly unbalanced or where the data can be represented by keys that are not necessarily alphanumeric starting with a letter or when the datasets are to be extracted from different nested levels.
The common way to go around this is to code everything needed in a tJavaFlex component like:
- Given the json:
{"arr":[{"id":1, "next":2},{"id":2}, {"id":3, "next":4}]}
- We build the below sample job:
- Using the below in the tJavaFlex
//imports import java.util.Map.Entry; import java.util.Set; import org.json.simple.JSONObject; import org.json.simple.JSONArray; import org.json.simple.parser.JSONParser; import java.util.ArrayList; import java.io.ByteArrayInputStream; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.FileReader; import java.io.InputStream; import java.io.InputStreamReader; //start JSONParser parser = new JSONParser(); JSONObject jsonObject = (JSONObject) parser.parse(new FileReader("/opt/samples/big.json")); JSONArray arr = (JSONArray) jsonObject.get("arr"); for(int i = 0; i < arr.size(); i++) { //main JSONObject item = (JSONObject) arr.get(i); Long itemId = (Long) item.get("id"); Long next = (Long) item.get("next"); row5.id = itemId; row5.next = next; //end }
- Once we run it we correctly get our list of id and next values:
[statistics] connecting to socket on port 3472 [statistics] connected 1|2 2| 3|4 [statistics] disconnected Job sample ended at 10:21 14/02/2013. [exit code=0]
JsonPath
Using JsonPath allows for a shorter implementation though://import ... import com.jayway.jsonpath.JsonPath; ... //main ... Long itemId = (Long) JsonPath.read(item, "$.id"); Long next = (Long) JsonPath.read(item, "$.next"); ...Let us suppose we have a little bit more complicated JSON:
{"arr":[{"book":{"id":1, "next":2}}, {"book":{"id":2}}, {"book":{"id":3, "next":4}}]}If you want to parse nested properties and the JSON is unbalanced like in this case (there is no "next for book.id=2) you will need to catch PathNotFoundException:
//import ... import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.PathNotFoundException; ... //main ... Long itemId = ""; Long next = ""; //try needed only for nested path like in cases like "$.book.name" try { itemId = (Long) JsonPath.read(item, "$.book.id"); } catch (PathNotFoundException e) { } try { next = (Long) JsonPath.read(item, "$.book.next"); } catch (PathNotFoundException e) { } ...This approach requires the below libraries which you can get from json-path project:
json-path-0.9.0.jar slf4j-api-1.7.5.jar json-smart.1.2.jar
2 comments:
Thank you for posting this! I ran into this exact issue with the tFileInputJSON component and was looking for a workaround. This worked beautifully for me. Great writeup!
@arawan. Glad it helped. Cheers, -Nestor
Post a Comment