How to convert a partly nested XML to data frame using xml2

Here is a way to do it using tidyverse more than xml2 itself because read xml is converted as list directly.

This use the new tidyr function currently in dev version for nesting list.
Also, readr as a type_convert function to activate its parsers on a data.frame

xml_doc <-"
<DATA>

    <RECORD>
        <VAR1>string1</VAR1>
        <VAR2>1</VAR2>
        <VAR3>2.3</VAR3>
        <VAR4>TRUE</VAR4>
    </RECORD>

    <RECORD>
        <VAR1>string2</VAR1>
        <VAR2>2</VAR2>
        <VAR3>3.4</VAR3>
        <VAR4>FALSE</VAR4>
    </RECORD>

    <RECORD>
        <VAR1>string3</VAR1>
        <VAR2>3</VAR2>
        <VAR3>4.5</VAR3>
        <VAR4>TRUE</VAR4>
    </RECORD>

</DATA>
"

library(xml2)

# convert xml as a R list
doc <- as_list(read_xml(xml_doc))
str(doc$DATA, 1)
#> List of 3
#>  $ RECORD:List of 4
#>  $ RECORD:List of 4
#>  $ RECORD:List of 4
library(tidyr)
packageVersion("tidyr")
#> [1] '0.8.3.9000'
# put list into a one column tible
tibble::as_tibble(doc) %>%
  # new tidyr function
  unnest_wider(DATA) %>%
  # unnest same length list cols
  unnest(cols = names(.)) %>%
  unnest(cols = names(.)) %>%
  # convert using readr parser
  readr::type_convert()
#> Parsed with column specification:
#> cols(
#>   VAR1 = col_character(),
#>   VAR2 = col_double(),
#>   VAR3 = col_double(),
#>   VAR4 = col_logical()
#> )
#> # A tibble: 3 x 4
#>   VAR1     VAR2  VAR3 VAR4 
#>   <chr>   <dbl> <dbl> <lgl>
#> 1 string1     1   2.3 TRUE 
#> 2 string2     2   3.4 FALSE
#> 3 string3     3   4.5 TRUE

Created on 2019-08-05 by the reprex package (v0.3.0)

Not sure it is more efficient than XML but if you want not to use XML it is an option.
xml2 has no equivalent of xmlToDataFrame as far as I know. :thinking: