2017-04-24 2 views
0

J'ai 80 000 fichiers XML censés utiliser le même format. Cependant, ce n'est clairement pas le cas. Pour cette raison, je tente d'identifier tous les nœuds existants et les enfants dans les fichiers.Identifier tous les parents et enfants possibles dans les listes

J'ai importé les fichiers XML en tant que listes, en utilisant le package XML, et dans ce qui suit j'ai décrit mon entrée et ma sortie désirée.

Entrée (listes de listes):

XML1 <- list(name = "Company Number 1", 
      adress = list(street = "JP Street", number = "12"), 
      product = "chicken") 

XML2 <- list(name = "Company Number 2", 
      company_adress = list(street = "House Street", number = "93"), 
      invoice = list(quantity = "2", product = "phone")) 

XML3 <- list(company_name = "Company Number 3", 
      adress = list(street = "Lake Street", number = "1"), 
      invoice = list(quantity = "2", product = "phone", list(note = "Phones are refurbished"))) 

sortie (structure arborescente dans les fichiers avec un nombre d'occurrences à leafs):

List of 5 
$ name   : num 2 
$ company_name : num 1 
$ adress  :List of 2 
    ..$ street: num 2 
    ..$ number: num 2 
$ company_adress:List of 2 
    ..$ street: num 1 
    ..$ number: num 1 
$ invoice  :List of 3 
    ..$ quantity: num 2 
    ..$ product : num 2 
    ..$   :List of 1 
    .. ..$ note: num 1 
$ product  : num 1 

Y at-il un paquet qui peut faire quelque chose le long de cette ligne , ou dois-je écrire une fonction qui le fait moi-même?

Répondre

0

J'ai programmé une boucle récursive qui résout le problème. Ce n'est pas élégant, mais ça fait l'affaire.

La fonction prend une liste imbriquée et un vecteur vide.

# Summary tree for storing results 
summary_tree <- list() 

# Function 
tree_merger <- function(tree, position) { 
    # Testing if at the leaf of a tree 
    if (is.character(tree) | is.null(tree)) { 
    print("DONE") 
    } else { 
    # Position in tree 
    if (length(position) == 0) { 
     # Names of nodes 
     tree_names <- names(tree) 

     # Adding one to each name 
     for (i in 1:length(tree_names)) { 
     if (is.null(summary_tree[[tree_names[i]]])) { 
      summary_tree[[tree_names[i]]] <<- list(1) 
     } else { 
      summary_tree[[tree_names[i]]] <<- list(summary_tree[[tree_names[i]]][[1]] + 1) 
     } 

     # Running function on new tree 
     tree_merger(tree[[tree_names[i]]], c(position, tree_names[i])) 
     } 
    } else { 
     # Names of nodes 
     tree_names <- names(tree) 

     # Finding position in tree to save information 
     position_string <- NULL 
     for (p in position) { 
     position_string <- paste(position_string, "[[\"", p, "\"]]", sep = "") 
     } 
     position_string <- paste("summary_tree", position_string, sep = "") 

     # Adding one to each position 
     for (i in 1:length(tree_names)) { 
     position_string_full <<- paste(position_string, "[[\"", tree_names[i], "\"]]", sep = "") 

     # Adding to position 
     if(is.null(eval(parse(text=position_string_full)))) { 
     eval(parse(text=paste(position_string_full, "<<- list(1)"))) 
     } else { 
      eval(parse(text=paste(position_string_full, "<<- list(", position_string_full ,"[[1]] + 1)"))) 
     } 

     # Running function on new tree 
     tree_merger(tree[[tree_names[i]]], c(position, tree_names[i])) 
     } 
    } 
    } 
} 

Si quelqu'un doit fonctionner dans le même problème, il convient de noter que le code sur la façon dont vous quittez la récursion devrait être probablement changé. Pour mes fichiers XML, tout "leafs" se termine par une chaîne ou NULL. Dans d'autres listes de listes, il peut s'agir d'autres types de valeurs.