Googme Googme - 3 months ago 7
R Question

How to create XML from .csv properly?

I would like to create a

XML
file from a
.csv
file. I have some difficulties to get the desired structure:

<?xml version="1.0" encoding="UTF-8"?>
<document>
<employee ID="1">
<Name>Steve</Name>
<City>Boston</City>
<Age>33</Age>
</employee>
<employee ID="2">
<Name>Michael</Name>
<City>Dallas</City>
<Age>45</Age>
</employee>
<employee ID="3">
<Name>John</Name>
<City>New York</City>
<Age>89</Age>
</employee>
<employee ID="4">
<Name>Thomas</Name>
<City>LA</City>
<Age>62</Age>
</employee>
<employee ID="5">
<Name>Clint</Name>
<City>Paris</City>
<Age>30</Age>
</employee>
</document>


What I have tried:

library(XML)

# Some data
df <-
read.csv(textConnection('"ID","Name","City","Age"
"1","Steve","Boston",33
"2","Michael","Dallas",45
"3","John","New York",89
"4","Thomas","LA",62
"5","Clint","Paris",30'),
as.is=TRUE)

xml <- xmlTree()
xml$addTag("document", close=FALSE)
for (i in 1:nrow(df)) {
xml$addTag("employee", close=FALSE)
for (j in names(df)) {
xml$addTag(j, df[i, j])
}
xml$closeTag()
}
xml$closeTag()


Which looks almost as desired, but where ID is beneath
employee
rather then on the same line and the encoding is not in the header:

<?xml version="1.0"?>

<document>
<employee>
<ID>1</ID>
<Name>Steve</Name>
<City>Boston</City>
<Age>33</Age>
</employee>
<employee>
<ID>2</ID>
<Name>Michael</Name>
<City>Dallas</City>
<Age>45</Age>
</employee>
<employee>
<ID>3</ID>
<Name>John</Name>
<City>New York</City>
<Age>89</Age>
</employee>
<employee>
<ID>4</ID>
<Name>Thomas</Name>
<City>LA</City>
<Age>62</Age>
</employee>
<employee>
<ID>5</ID>
<Name>Clint</Name>
<City>Paris</City>
<Age>30</Age>
</employee>
</document>

Answer

Use addNode instead of addTag. They are identical

> identical(xml$addTag, xml$addNode)
[1] TRUE

so its a matter of preference. You can give an attrs argument to add the ID attribute. You can add the encoding when you save the file:

library(XML)
df <-
  read.csv(textConnection('"ID","Name","City","Age"
                          "1","Steve","Boston",33
                          "2","Michael","Dallas",45
                          "3","John","New York",89
                          "4","Thomas","LA",62
                          "5","Clint","Paris",30'),
           as.is=TRUE)

xml <- xmlTree("document")
for (i in 1:nrow(df)) {
  xml$addNode("employee", attrs = c(ID = df[i,"ID"]), close = FALSE)
  appNames <- names(df)[names(df) != "ID"]
  for (j in appNames) {
    xml$addNode(j, df[i, j])
  }
  xml$closeNode()
}
xml$closeNode()
saveXML(xml$doc(), "text.xml", encoding = "UTF-8")
xmlParse("text.xml")
<?xml version="1.0" encoding="UTF-8"?>
<document>
  <employee ID="1">
    <Name>Steve</Name>
    <City>Boston</City>
    <Age>33</Age>
  </employee>
  <employee ID="2">
    <Name>Michael</Name>
    <City>Dallas</City>
    <Age>45</Age>
  </employee>
  <employee ID="3">
    <Name>John</Name>
    <City>New York</City>
    <Age>89</Age>
  </employee>
  <employee ID="4">
    <Name>Thomas</Name>
    <City>LA</City>
    <Age>62</Age>
  </employee>
  <employee ID="5">
    <Name>Clint</Name>
    <City>Paris</City>
    <Age>30</Age>
  </employee>
</document>