protected static final Object copyChildren(String parentName, Node source, LinkedHashMap<String, Object> map) {

		// Node name
		LinkedList<Object> array = null;
		boolean isArray = isArray(source);
		String name = source.getNodeName();
		if (name != null && !parentName.equals(name)) {
			map.put("_name", name);
		}

		// Copy attributes
		NamedNodeMap attributes = source.getAttributes();
		if (attributes != null) {
			int max = attributes.getLength();
			for (int i = 0; i < max; i++) {
				Node attribute = attributes.item(i);
				name = attribute.getNodeName();
				String value = attribute.getNodeValue();
				if (name != null && value != null) {
					map.put('@' + name, value);
				}
			}
		}

		// JSON array?
		if (isArray) {
			array = new LinkedList<>();
			if (hasProperties(source)) {
				map.put("_items", array);
			}
		}

		// Loop on children
		NodeList children = source.getChildNodes();
		if (children != null) {
			int max = children.getLength();
			for (int i = 0; i < max; i++) {
				Node child = children.item(i);
				if (child.getNodeType() != Node.ELEMENT_NODE) {
					continue;
				}
				String value = getTextValue(child);
				if (value != null && !hasProperties(child)) {

					// Property
					name = child.getNodeName();
					if (name != null) {
						if (isArray) {
							putWithType(null, array, name, value);
						} else {
							putWithType(map, null, name, value);
						}
					}

				} else {

					// Substructure
					LinkedHashMap<String, Object> subTree = new LinkedHashMap<>();
					if (isArray) {
						name = "";
						array.add(subTree);
					} else {
						name = child.getNodeName();
						map.put(name, subTree);
					}
					String text = getTextValue(child);
					if (text != null && !text.isEmpty()) {
						subTree.put("_text", text);
					}

					// Recursive copy
					Object result = copyChildren(name, child, subTree);
					if (result != subTree) {
						map.put(name, result);
					}
				}
			}
		}
		return map.isEmpty() && array != null ? array : map;
	}
protected static final Object copyChildren ( String parentName , Node source , LinkedHashMap < String , Object > map ) { LinkedList < Object > array = null ; boolean isArray = isArray ( source ) ; String name = source . getNodeName ( ) ; if ( name != null && ! parentName . equals ( name ) ) { map . put ( "_name" , name ) ; } NamedNodeMap attributes = source . getAttributes ( ) ; if ( attributes != null ) { int max = attributes . getLength ( ) ; for ( int i = 0 ; i < max ; i ++ ) { Node attribute = attributes . item ( i ) ; name = attribute . getNodeName ( ) ; String value = attribute . getNodeValue ( ) ; if ( name != null && value != null ) { map . put ( '@' + name , value ) ; } } } if ( isArray ) { array = new LinkedList < > ( ) ; if ( hasProperties ( source ) ) { map . put ( "_items" , array ) ; } } NodeList children = source . getChildNodes ( ) ; if ( children != null ) { int max = children . getLength ( ) ; for ( int i = 0 ; i < max ; i ++ ) { Node child = children . item ( i ) ; if ( child . getNodeType ( ) != Node . ELEMENT_NODE ) { continue ; } String value = getTextValue ( child ) ; if ( value != null && ! hasProperties ( child ) ) { name = child . getNodeName ( ) ; if ( name != null ) { if ( isArray ) { putWithType ( null , array , name , value ) ; } else { putWithType ( map , null , name , value ) ; } } } else { LinkedHashMap < String , Object > subTree = new LinkedHashMap < > ( ) ; if ( isArray ) { name = "" ; array . add ( subTree ) ; } else { name = child . getNodeName ( ) ; map . put ( name , subTree ) ; } String text = getTextValue ( child ) ; if ( text != null && ! text . isEmpty ( ) ) { subTree . put ( "_text" , text ) ; } Object result = copyChildren ( name , child , subTree ) ; if ( result != subTree ) { map . put ( name , result ) ; } } } } return map . isEmpty ( ) && array != null ? array : map ; }
--- RECURSIVE STRUCTURE BUILDER ---