Skip to contents

Create an XML fragment using readable R syntax, that can be used to create a string, an xml2::xml_document or as a building block for more complex XML documents.

Usage

xml_fragment(...)

Arguments

...

nest named elements and characters to include in the fragment (see example)

Value

an xml_fragment, list object that can be converted to an xml2::xml_document or character string

Details

An xml_fragment is built using:

  • named frag elements, each name is a tag name, and the value is the contents of the tag, e.g. name = "value" becomes <name>value</name>. The value can be a nested frag object, a character string or a numeric value.

  • .attr attributes, which is set on current element, or on the frag where it is specified

  • unnamed elements, which are added as text nodes.

  • data_frag() function that can be used to convert a data.frame to an xml fragment, in which each row is a set of xml elements (columns).

  • tag() function that can be used to create a tag with attributes and (optional) text.

An xml_doc is a special case of an xml_fragment that contains exactly one root element, and errors when this is not the case.

A resulting xml_fragment object can be converted to an xml2::xml_document with xml2::as_xml_document() or to a character string with as.character(). Both methods are fast using a performant c++ implementation.

See also

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 ...