How to create xml from R objects, e.g., is there a 'listToXml' function?
The function newXMLNode
does what you need, i.e., write XML output. See the detailed help and examples in ?newXMLNode
for more details. Here is a short extract:
library(XML) top = newXMLNode("a")newXMLNode("b", attrs=c(x=1, y='abc'), parent=top)newXMLNode("c", "With some text", parent=top)top
Resulting in:
<a> <b x="1" y="abc"/> <c>With some text</c></a>
I am surprised that no function already exists for this -- surely there's something already packaged out there.
Regardless, I use the following script to accomplish this:
root <- newXMLNode("root")li <- list(a = list(aa = 1, ab=2), b=list(ba = 1, bb= 2, bc =3))listToXML <- function(node, sublist){ for(i in 1:length(sublist)){ child <- newXMLNode(names(sublist)[i], parent=node); if (typeof(sublist[[i]]) == "list"){ listToXML(child, sublist[[i]]) } else{ xmlValue(child) <- sublist[[i]] } } }listToXML(root, li)
You can use the XML::saveXML() function to grab this as a character, if you prefer.
Here is the listToXML
function that we ended up creating
At first I adapted the answer by @Jeff
listToXml <- function(item, tag){ if(typeof(item)!='list') return(xmlNode(tag, item)) xml <- xmlNode(tag) for(name in names(item)){ xml <- append.xmlNode(xml, listToXml(item[[name]], name)) } return(xml)}
But since the function has benefited from further development:
##' Convert List to XML##'##' Can convert list or other object to an xml object using xmlNode##' @title List to XML##' @param item ##' @param tag xml tag##' @return xmlNode##' @export##' @author David LeBauer, Carl Davidson, Rob KooperlistToXml <- function(item, tag) { # just a textnode, or empty node with attributes if(typeof(item) != 'list') { if (length(item) > 1) { xml <- xmlNode(tag) for (name in names(item)) { xmlAttrs(xml)[[name]] <- item[[name]] } return(xml) } else { return(xmlNode(tag, item)) } } # create the node if (identical(names(item), c("text", ".attrs"))) { # special case a node with text and attributes xml <- xmlNode(tag, item[['text']]) } else { # node with child nodes xml <- xmlNode(tag) for(i in 1:length(item)) { if (names(item)[i] != ".attrs") { xml <- append.xmlNode(xml, listToXml(item[[i]], names(item)[i])) } } } # add attributes to node attrs <- item[['.attrs']] for (name in names(attrs)) { xmlAttrs(xml)[[name]] <- attrs[[name]] } return(xml)}