Skip to content
Snippets Groups Projects
export_utils.R 3.82 KiB
Newer Older
  • Learn to ignore specific revisions
  • #'@description Recursive function to restructure objects so
    #' xml2::as_xml_document() function will convert them to the desired XML format
    #'@param object An object (so far works for r2ogs6 class objects, strings,
    #' numbers, lists and vectors)
    
    #'@param object_name Optional: The object name. If not supplied, this function
    #' will try to guess the tag name by deparsing the 'object' parameter
    
    #'@param attribute_names Optional: A character vector containing names of
    #' attributes or attribute nodes
    #'@param flatten_on_exp Optional: This is for vectors which will be flattened
    #' to a string in XML
    
    to_node <- function(object, object_name = "",
                        attribute_names = character(),
                        flatten_on_exp = character()){
    
        assertthat::assert_that(is.character(attribute_names))
        assertthat::assert_that(is.character(flatten_on_exp))
    
        if(is.null(object_name) || object_name == ""){
            object_name <- deparse(substitute(object))
    
            if(any(grep("\\$", object_name))){
                object_name <- unlist(strsplit(object_name, "$", fixed = TRUE))[[2]]
            }
        }
    
        #Recursion ends here
        if(assertthat::is.string(object) ||
           assertthat::is.number(object) ||
           (is.vector(object) &&
            (object_name %in% flatten_on_exp ||
            object_name %in% attribute_names))){
    
            if(object_name %in% flatten_on_exp){
                    ret_list <- list(list(paste(object, collapse = " ")))
                    names(ret_list)[[1]] <- object_name
                    return(invisible(ret_list))
            }
    
            if(object_name %in% attribute_names){
    
                if(length(object) > 1){
                    attr_node <- list(structure(list()))
                    names(attr_node)[[1]] <- object_name
    
                    for(i in seq_len(length(object))){
                        attr(attr_node[[1]], names(object)[[i]]) <- object[[i]]
                    }
    
                    return(invisible(attr_node))
                }
    
                ret_vect <- c(object)
                names(ret_vect)[[1]] <- object_name
    
                return(invisible(ret_vect))
    
            }else{
                ret_list <- list(list(object))
                names(ret_list)[[1]] <- object_name
    
                return(invisible(ret_list))
            }
        }
    
        #For r2ogs6 classes, we need recursion
        if(any(grepl("r2ogs6_", class(object), fixed = TRUE))){
    
            class_name <- class(object)[[1]]
    
            param_names <- names(as.list(formals(paste0("new_", class_name))))
    
            object_node <- list(structure(list()))
    
            names(object_node)[[1]] <- get_class_tag_name(class_name)
    
    
            for(i in seq_len(length(param_names))){
                get_param_call <- paste0("object$", param_names[[i]])
                param_value <- eval(parse(text = get_param_call))
    
                if(is.null(param_value)){
                    next
                }
    
                param_node <- to_node(param_value,
                                      param_names[[i]],
                                      object$attr_names,
                                      object$flatten_on_exp)
    
                #Handle depending on if it's a child or attribute
                if(is.list(param_node)){
    
                    object_node[[1]][[length(object_node[[1]])+1]] <-
                        param_node
    
                    attr(object_node[[1]], names(param_node)[[1]]) <-
                        param_node[[1]]
    
                }
            }
            return(invisible(object_node))
        }
    
        if(is.list(object) || is.vector(object)){
    
            object_node <- list(structure(list()))
            names(object_node)[[1]] <- object_name
    
            for(i in seq_len(length(object))){
    
                element_node <- to_node(object[[i]],
                                        names(object)[[i]],
                                        attribute_names)
    
                object_node[[1]] <- c(object_node[[1]], element_node)
            }
    
            return(invisible(object_node))
        }