Skip to contents

xmlwriter is an R package that provides a simple interface for creating XML documents and fragments from R. It provides a simple elegant syntax for creating xml_fragments and furthermore contains a feed-forward API that allows you to write xml.

Details

xmlwriter's xml generation from R lists is fast, implemented in C++ using Rcpp.

xmlwriter provides two different ways to create xml documents:

  • a light weight R syntax using xml_doc(), xml_fragment() and frag(), creating an xml fragment that can be easily translated into a xml string or xml2::xml_document object

  • a feed-forward API using xmlbuilder() that allows you to create xml documents in a feed-forward manner.

It implements several xml2 methods:

  • as_xml_document.xml_fragment()

  • as_list.xml_fragment()

  • write_xml.xml_fragment()

See also

Author

Maintainer: Edwin de Jonge edwindjonge@gmail.com (ORCID)

Examples

doc <- xml_fragment(
  study = frag(
    .attr = c(id="1"),
    person = frag(
      .attr = c(id = "p1"),
      name = "John Doe",
      age = 30
    ),
    person = frag(
      name = "Jane Doe",
      age = 25,
      address = frag(street = "123 Main St", city = "Springfield"),
      "This is a text node"
    )
  )
)

print(doc)
#> {xml_fragment}
#> <study id="1">
#>   <person id="p1">
#>     <name>John Doe</name>
#>     <age>30</age>
#>   ... 
if (require("xml2")){
  as_xml_document(doc)
}
#> {xml_document}
#> <study id="1">
#> [1] <person id="p1">\n  <name>John Doe</name>\n  <age>30</age>\n</person>
#> [2] <person><name>Jane Doe</name><age>25</age><address><street>123 Main St</s ...

# you can create a function to generate an xml fragment:
person_frag <- function(name, age, id){
  tag("person", id = id) / frag(
    name = name,
    age  = age,
    address = frag(
      street = "123 Main St",
      city = "Springfield"
    )
  )
}

# xml_doc is a xml_fragment with the restriction of having one root element
doc2 <- xml_doc("study") / (
  person_frag("John Doe", 30, "p1") +
  person_frag("Jane Doe", 25, "p2")
)

print(doc2)
#> {xml_doc,xml_fragment}
#> <?xml version='1.0' encoding='UTF-8'?>
#>  <study>
#>   <person id="p1">
#>     <name>Joh... 

if (require("xml2")){
  as_xml_document(doc2)
}
#> {xml_document}
#> <study>
#> [1] <person id="p1">\n  <name>John Doe</name>\n  <age>30</age>\n  <address>\n ...
#> [2] <person id="p2">\n  <name>Jane Doe</name>\n  <age>25</age>\n  <address>\n ...

# a fragment can have multiple root elements
fgmt <- person_frag("John Doe", 30, id = "p1") +
  person_frag("Jane Doe", 25, id = "p2")


print(fgmt)
#> {xml_fragment (2)}
#> [1]<person id="p1">
#>   <name>John Doe</name>
#>   <age>30</age>
#>   <address>
#>     <street...
#> [2]<person id="p2">
#>   <name>Jane Doe</name>
#>   <age>25</age>
#>   <address>
#>     <street...
#> ...

if (require("xml2")){
  # as_xml_document won't work because it expects a single root element,
  # so we retrieve a nodeset instead
  as_xml_nodeset(fgmt)
}
#> {xml_nodeset (2)}
#> [1] <person id="p1">\n  <name>John Doe</name>\n  <age>30</age>\n  <address>\n ...
#> [2] <person id="p2">\n  <name>Jane Doe</name>\n  <age>25</age>\n  <address>\n ...

iris_xml <- xml_doc("fieldstudy", id = "iris", doi ="10.1111/j.1469-1809.1936.tb02137.x") /
  frag(
    source = "Fisher, R. A. (1936) The use of multiple measurements in
taxonomic problems. Annals of Eugenics, 7, Part II, 179–188.",
    data = data_frag(iris, row_tag = "obs")
  )

print(iris_xml, max_characters = 300)
#> {xml_doc,xml_fragment}
#> <?xml version='1.0' encoding='UTF-8'?>
#>  <fieldstudy id="iris" doi="10.1111/j.1469-1809.1936.tb02137.x">
#>   <source>Fisher, R. A. (1936) The use of multiple measurements in
#> taxonomic problems. Annals of Eugenics, 7, Part II, 179–188.</source>
#>   <data>
#>     <obs>
#>       <Sepal.Length>5.1</Sepal.Length>
#>  ... 

if (require("xml2")){
  as_xml_document(iris_xml)
}
#> {xml_document}
#> <fieldstudy id="iris" doi="10.1111/j.1469-1809.1936.tb02137.x">
#> [1] <source>Fisher, R. A. (1936) The use of multiple measurements in\ntaxonom ...
#> [2] <data>\n  <obs>\n    <Sepal.Length>5.1</Sepal.Length>\n    <Sepal.Width>3 ...