I have a parent child relationship (Tree Structure) in database and I want to traverse it and create a json object out of it.
My Database Parent child relationship structure (Demo Data).
child_id parent_id Item_Name
1 1 Country
2 1 Australia
3 2 Victoria
4 2 Queensland
5 1 Canada
6 5 British Columbia
7 6 Vancouver
8 8 Songs
9 8 Song1
10 8 Song2
11 10 lyrics 1st
12 10 lyrics 2nd
13 13 Germany
14 14 England
15 14 London
How this works
if(child_id == parent_id)
{
// This item is parent. Like Country,Songs,Germany, England
} else {
// This item is child. Like Australia, Song1, Vancouver etc.
}
Now, I know how to traverse a structure like this, but having trouble converting it to json object's.
Pseudo Code DFS Tree
Get all parent's
List data = fetch data from table where parent_id=child_id
Now traverse this data
Recursively iterate through child elements
get child_id from data object and query on database it as parent_id, to get its child elements and so on.
However, how to convert it into JSON Object's like this
{
"country": [
{
"Australia": [
"Victoria",
"Queensland"
]
},
{
"Canada": [
{
"British Columbia": [
"Vancouver"
]
}
]
}
]
},
{
"Songs": [
"Songs1",
{
"Songs2": [
"lyrics 1st",
"lyrics 2nd"
]
}
]
},
{
"Germany": null
},
{
"England": ["London"]
}
Or a json Object in which parent-child relationship is maintained .
First of all the JSON you have provided is not a valid JSON. So that I have added an parent root node when generating the JSON.
If you had a root node defined in your dataset there will be small change to your structure as you cannot maintain parent_Id = child_id relationship as the current data set.So there will be a modification for the solution also.
First you need to map your data into some parent-child supported data type. I have created Node.java for that purpose. Introduced the addChild
method to add children one by one.
import java.util.ArrayList;
import java.util.List;
public class Node
{
private String nodeName;
private java.util.List<Node> children = new ArrayList<Node>();
public Node( String nodeName )
{
this.nodeName = nodeName;
}
public List<Node> getChildren()
{
return children;
}
public void setChildren( List<Node> children )
{
this.children = children;
}
public String getNodeName()
{
return nodeName;
}
public void setNodeName( String nodeName )
{
this.nodeName = nodeName;
}
public void addChild( Node node )
{
this.children.add( node );
}
}
And for your original data type, I created Mapping.java
public class Mapping
{
private int parentId;
private int childId;
private String ItemName;
public Mapping( int parentId, int childId, String itemName )
{
this.parentId = parentId;
this.childId = childId;
ItemName = itemName;
}
public int getParentId()
{
return parentId;
}
public void setParentId( int parentId )
{
this.parentId = parentId;
}
public int getChildId()
{
return childId;
}
public void setChildId( int childId )
{
this.childId = childId;
}
public String getItemName()
{
return ItemName;
}
public void setItemName( String itemName )
{
ItemName = itemName;
}
}
Now loading and data and populating the Node objects and getting the final Json is done here. I am using an object reference map here because we cannot guarantee the order of mappings in your database. Since children are assigned to the object reference of the parent, after completing the assignment, we will have our parent-child structure. The two loops are also used for the same reason. We need to ensure map is having all nodes before starting to build the structure.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ParentChild
{
public static void main( String[] args )
{
List<Mapping> list = new ArrayList<Mapping>();
list.add( new Mapping( 1, 1, "Country" ) );
list.add( new Mapping( 1, 2, "Australia" ) );
list.add( new Mapping( 2, 3, "Victoria" ) );
list.add( new Mapping( 2, 4, "Queensland" ) );
list.add( new Mapping( 1, 5, "Canada" ) );
list.add( new Mapping( 5, 6, "British Columbia" ) );
list.add( new Mapping( 6, 7, "Vancouver" ) );
list.add( new Mapping( 8, 8, "Songs" ) );
list.add( new Mapping( 8, 9, "Song1" ) );
list.add( new Mapping( 8, 10, "Song2" ) );
list.add( new Mapping( 10, 11, "lyrics 1st" ) );
list.add( new Mapping( 10, 12, "lyrics 2nd" ) );
list.add( new Mapping( 13, 13, "Germany" ) );
list.add( new Mapping( 14, 14, "England" ) );
list.add( new Mapping( 14, 15, "London" ) );
Map<Integer, Node> map = new HashMap<Integer, Node>();
map.put( -1, new Node( "root" ) ); // give index -1 for the root
for( Mapping mapping : list ) // keep a map of nodes by child id
{
map.put( mapping.getChildId(), new Node( mapping.getItemName() ) );
}
for( Mapping mapping : list )
{
if( mapping.getParentId() == mapping.getChildId() )
{
map.get( -1 ).addChild( map.get( mapping.getChildId() ) ); // add to the root
}
else
{
Node node = map.get( mapping.getParentId() );
Node childNode = map.get( mapping.getChildId() );
node.addChild( childNode ); // add to the relevant parent
}
}
StringBuilder json = new StringBuilder();
writeJson( map.get( -1 ), json ); // root node is enough
System.out.println( json );
}
private static void writeJson( Node node, StringBuilder json )
{
if( node.getChildren().isEmpty() ) // no children. return just the node name
{
json.append( "\"" ).append( node.getNodeName() ).append( "\"" );
}
else
{
json.append( "{\"" ).append( node.getNodeName() ).append( "\": [" );
List<Node> children = node.getChildren();
for( int i = 0; i < children.size(); i++ )
{
Node child = children.get( i );
writeJson( child, json ); // call recursively
if( i != children.size() - 1 ) // skip , for the last child
{
json.append( "," );
}
}
json.append( "]}" );
}
}
}
I have used a recursive method to build the json.
The resulting JSON
{
"root":[
{
"Country":[
{
"Australia":[
"Victoria",
"Queensland"
]
},
{
"Canada":[
{
"British Columbia":[
"Vancouver"
]
}
]
}
]
},
{
"Songs":[
"Song1",
{
"Song2":[
"lyrics 1st",
"lyrics 2nd"
]
}
]
},
"Germany",
{
"England":[
"London"
]
}
]
}
Hope it helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.