private void build(List<String> paths,String fieldName,boolean multiValued,boolean record,int flags){
  String xpseg=paths.remove(0);
  if (paths.isEmpty() && xpseg.startsWith("@")) {
    if (attributes == null) {
      attributes=new ArrayList<>();
    }
    xpseg=xpseg.substring(1);
    attributes.add(new Node(xpseg,fieldName,multiValued));
  }
 else   if (xpseg.length() == 0) {
    xpseg=paths.remove(0);
    if (wildCardNodes == null)     wildCardNodes=new ArrayList<>();
    Node n=getOrAddNode(xpseg,wildCardNodes);
    if (paths.isEmpty()) {
      n.hasText=true;
      n.fieldName=fieldName;
      n.multiValued=multiValued;
      n.flatten=flags == FLATTEN;
    }
 else {
      n.build(paths,fieldName,multiValued,record,flags);
    }
  }
 else {
    if (childNodes == null)     childNodes=new ArrayList<>();
    Node n=getOrAddNode(xpseg,childNodes);
    if (paths.isEmpty()) {
      if (record) {
        n.isRecord=true;
        n.forEachPath=fieldName;
      }
 else {
        n.hasText=true;
        n.fieldName=fieldName;
        n.multiValued=multiValued;
        n.flatten=flags == FLATTEN;
      }
    }
 else {
      n.build(paths,fieldName,multiValued,record,flags);
    }
  }
}

private void build ( List < String > paths , String fieldName , boolean multiValued , boolean record , int flags ) { String xpseg = paths . remove ( 0 ) ; if ( paths . isEmpty ( ) && xpseg . startsWith ( "@" ) ) { if ( attributes == null ) { attributes = new ArrayList < > ( ) ; } xpseg = xpseg . substring ( 1 ) ; attributes . add ( new Node ( xpseg , fieldName , multiValued ) ) ; } else if ( xpseg . length ( ) == 0 ) { xpseg = paths . remove ( 0 ) ; if ( wildCardNodes == null ) wildCardNodes = new ArrayList < > ( ) ; Node n = getOrAddNode ( xpseg , wildCardNodes ) ; if ( paths . isEmpty ( ) ) { n . hasText = true ; n . fieldName = fieldName ; n . multiValued = multiValued ; n . flatten = flags == FLATTEN ; } else { n . build ( paths , fieldName , multiValued , record , flags ) ; } } else { if ( childNodes == null ) childNodes = new ArrayList < > ( ) ; Node n = getOrAddNode ( xpseg , childNodes ) ; if ( paths . isEmpty ( ) ) { if ( record ) { n . isRecord = true ; n . forEachPath = fieldName ; } else { n . hasText = true ; n . fieldName = fieldName ; n . multiValued = multiValued ; n . flatten = flags == FLATTEN ; } } else { n . build ( paths , fieldName , multiValued , record , flags ) ; } } }
build a node tree structure representing all xpaths of intrest to us . this must be done before parsing of the xml stream starts . each node holds one portion of an xpath . taking each xpath segment in turn this method walks the node tree and finds where the new segment should be inserted . it creates a node representing a field ' s name , xpath and some flags and inserts the node into the node tree .
