xml2/0000755000176200001440000000000014765101672011145 5ustar liggesusersxml2/tests/0000755000176200001440000000000014760705221012302 5ustar liggesusersxml2/tests/testthat/0000755000176200001440000000000014765101672014147 5ustar liggesusersxml2/tests/testthat/test-xml_name.R0000644000176200001440000000405414727652467017065 0ustar liggesuserstest_that("xml_name() returns the name", { x <- read_xml("

Some text.

Some other.

No bold text

") children <- xml_children(x) x <- xml_find_first(children, ".//b|.//i") expect_equal(xml_name(x[[1]]), "b") expect_equal(xml_name(x[[2]]), "i") expect_equal(xml_name(x[[3]]), NA_character_) expect_equal(xml_name(x), c("b", "i", NA_character_)) }) test_that("qualified names returned when ns given", { x <- read_xml(test_path("ns-multiple-default.xml")) ns <- xml_ns(x) bars <- xml_children(xml_children(x)) expect_equal(xml_name(bars), c("bar", "bar")) expect_equal(xml_name(bars, ns), c("d1:bar", "d2:bar")) }) test_that("error if missing ns spec", { x <- read_xml(test_path("ns-multiple-default.xml")) ns <- xml_ns(x)[1] bars <- xml_children(xml_children(x)) expect_snapshot(error = TRUE, xml_name(bars, ns)) }) test_that("xml_name<- modifies the name", { x <- read_xml(test_path("ns-multiple-default.xml")) ns <- xml_ns(x) bars <- xml_children(xml_children(x)) bar <- bars[[1]] xml_name(bar) <- "foo" expect_equal(xml_name(bar), "foo") expect_equal(xml_name(bar, ns), "d1:foo") # ns is ignored xml_name(bar, ns) <- "bar" expect_equal(xml_name(bar), "bar") expect_equal(xml_name(bar, ns), "d1:bar") xml_name(bars) <- "foo" expect_equal(xml_name(bars), c("foo", "foo")) old_mss <- mss <- xml_missing() xml_name(mss) <- "foo" expect_identical(old_mss, mss) }) test_that("xml_set_name modifies the name", { x <- read_xml(test_path("ns-multiple-default.xml")) ns <- xml_ns(x) bars <- xml_children(xml_children(x)) bar <- bars[[1]] xml_set_name(bar, "foo") expect_equal(xml_name(bar), "foo") expect_equal(xml_name(bar, ns), "d1:foo") # ns is ignored xml_set_name(bar, "bar", ns) expect_equal(xml_name(bar), "bar") expect_equal(xml_name(bar, ns), "d1:bar") xml_set_name(bars, "foo") expect_equal(xml_name(bars), c("foo", "foo")) old_mss <- mss <- xml_missing() xml_set_name(mss, "foo") expect_identical(old_mss, mss) }) xml2/tests/testthat/test-format.R0000644000176200001440000000116714727652467016557 0ustar liggesuserstest_that("format.xml_node prints attributes for root nodes", { x <- read_xml("") expect_equal(format(x), "") }) test_that("format.xml_node prints namespaces for root nodes", { x <- read_xml("") expect_equal(format(x), "") y <- read_xml("") expect_equal(format(y), "") z <- read_xml("") expect_equal(format(z), "") }) xml2/tests/testthat/records.xml0000644000176200001440000000021714727652467016345 0ustar liggesusers &hoqc; xml2/tests/testthat/test-xml_attr.R0000644000176200001440000001627514727652467017127 0ustar liggesuserstest_that("missing attributes returned as NA by default", { x <- read_xml("") expect_equal(xml_attr(x, "id"), NA_character_) }) test_that("missing attributes returned as NA", { x <- read_xml("") expect_equal(xml_attr(x, "id", default = 1), "1") }) test_that("attributes are correctly found", { x <- read_xml("") expect_true(xml_has_attr(x, "id")) expect_false(xml_has_attr(x, "id2")) }) test_that("returning an attribute node prints properly", { x <- read_xml("") t1 <- xml_find_first(x, "//@c") expect_equal(format(t1), "") }) # Namespaces ------------------------------------------------------------------- # Default namespace doesn't apply to attributes test_that("qualified names returned when ns given", { x <- read_xml(test_path("ns-multiple.xml")) ns <- xml_ns(x) bars <- xml_children(xml_children(x)) attr <- xml_attrs(bars, ns) expect_named(attr[[1]], "f:id") expect_named(attr[[2]], "g:id") }) x <- read_xml(' ') doc <- xml_children(x)[[1]] docs <- xml_find_all(x, "//doc") ns <- xml_ns(x) test_that("qualified attributes get own values", { expect_equal(xml_attrs(doc, ns), c("b:id" = "b", "f:id" = "f", "id" = "")) }) test_that("unqualified name gets unnamespace attribute", { expect_equal(xml_attr(doc, "id", ns), "") }) test_that("namespace names gets namespaced attribute", { expect_equal(xml_attr(doc, "b:id", ns), "b") expect_equal(xml_attr(doc, "f:id", ns), "f") }) test_that("xml_attr<- modifies properties", { xml_attr(doc, "id", ns) <- "test" expect_equal(xml_attr(doc, "id", ns), "test") xml_attr(doc, "b:id", ns) <- "b_test" expect_equal(xml_attr(doc, "b:id", ns), "b_test") xml_attr(doc, "f:id", ns) <- "f_test" expect_equal(xml_attr(doc, "f:id", ns), "f_test") xml_attr(docs, "f:id", ns) <- "f_test2" expect_equal(xml_attr(docs, "f:id", ns), c("f_test2", "f_test2")) xml_attr(docs, "f:id", ns) <- NULL expect_equal(xml_attr(docs, "f:id", ns), c(NA_character_, NA_character_)) }) test_that("xml_attr<- recycles values", { x <- read_xml("") a <- xml_find_all(x, "a") xml_attr(a, "b") <- c("e", "f") expect_equal(xml_attr(a, "b"), c("e", "f")) }) test_that("xml_attrs<- modifies all attributes", { expect_error(xml_attrs(doc) <- 1, "`value` must be a named character vector or `NULL`") expect_error(xml_attrs(doc) <- "test", "`value` must be a named character vector or `NULL`") xml_attrs(doc, ns) <- c("b:id" = "b", "f:id" = "f", "id" = "test") expect_equal(xml_attrs(doc, ns), c("b:id" = "b", "id" = "test", "f:id" = "f")) xml_attrs(doc, ns) <- c("b:id" = "b", "f:id" = "f") expect_equal(xml_attrs(doc, ns), c("b:id" = "b", "f:id" = "f")) xml_attrs(doc, ns) <- c("b:id" = "b", "id" = "test") expect_equal(xml_attrs(doc, ns), c("b:id" = "b", "id" = "test")) expect_snapshot(error = TRUE, xml_attrs(docs) <- "test") xml_attrs(docs, ns) <- c("b:id" = "b", "id" = "test") expect_equal( xml_attrs(docs, ns), list( c("b:id" = "b", "id" = "test"), c("b:id" = "b", "id" = "test") ) ) xml_attrs(docs, ns) <- NULL expect_equal(xml_attrs(docs, ns), list(setNames(character(0), character()), setNames(character(0), character()))) }) test_that("xml_attr<- accepts non-character values", { x <- read_xml("") svg <- xml_root(x) xml_attr(svg, "width") <- 8L expect_equal(xml_attr(svg, "width"), "8") xml_attr(svg, "height") <- 12.5 expect_equal(xml_attr(svg, "height"), "12.5") expect_equal(xml_attrs(svg), c(width = "8", height = "12.5")) xml_attrs(svg) <- c(width = 14L, height = 23.45) expect_equal(xml_attrs(svg), c(width = "14", height = "23.45")) }) test_that("xml_attr<- can set empty strings, and removes attributes with NULL", { x <- read_xml("") xml_attr(x, "test") <- "" expect_equal(xml_attr(x, "test"), "") xml_attr(x, "test") <- NULL expect_equal(xml_attr(x, "test"), NA_character_) }) test_that("xml_attr<- removes namespaces if desired", { xml_attr(x, "xmlns:b") <- NULL expect_equal(xml_attrs(x), c("xmlns:f" = "http://foo.com")) }) test_that("xml_attr<- removes namespaces if desired", { x <- read_xml("") # cannot find //b with a default namespace expect_length(xml_find_all(x, "//b"), 0) # unless we specify it explicitly expect_length(xml_find_all(x, "//b"), 0) expect_length(xml_find_all(x, "//d1:b", xml_ns(x)), 1) # but can find it once we remove the namespace xml_attr(x, "xmlns") <- NULL expect_length(xml_find_all(x, "//b"), 1) # and add the old namespace back xml_attr(x, "xmlns") <- "tag:foo" expect_equal(xml_attr(x, "xmlns"), "tag:foo") expect_length(xml_find_all(x, "//b"), 0) expect_length(xml_find_all(x, "//d1:b", xml_ns(x)), 1) expect_equal(xml_attr(x, "xmlns"), "tag:foo") }) test_that("xml_attr<- removes prefixed namespaces if desired", { x <- read_xml("") # cannot find //b with a prefixed namespace expect_length(xml_find_all(x, "//b"), 0) # unless we specify it explicitly expect_length(xml_find_all(x, "//b"), 0) expect_length(xml_find_all(x, "//pre:b", xml_ns(x)), 1) # but can find it once we remove the namespace xml_attr(x, "xmlns:pre") <- NULL expect_length(xml_find_all(x, "//b"), 1) # and add the old namespace back xml_attr(x, "xmlns:pre") <- "tag:foo" xml_set_namespace(xml_children(x)[[1]], "pre") expect_equal(xml_attr(x, "xmlns:pre"), "tag:foo") expect_length(xml_find_all(x, "//b"), 0) expect_length(xml_find_all(x, "//pre:b", xml_ns(x)), 1) expect_equal(xml_attr(x, "xmlns:pre"), "tag:foo") }) test_that("xml_set_attr works identically to xml_attr<-", { content <- "" x <- read_xml(content) y <- read_xml(content) xml_attr(x, "a") <- "test" xml_set_attr(y, "a", "test") expect_equal(as.character(x), as.character(y)) bx <- xml_find_all(x, "//b") by <- xml_find_all(y, "//b") xml_attr(bx, "b") <- "test2" xml_set_attr(by, "b", "test2") expect_equal(as.character(x), as.character(y)) # No errors for xml_missing mss <- xml_find_first(bx, "./c") expect_no_error(xml_attr(mss[[2]], "b") <- "blah") expect_no_error(xml_set_attr(mss[[2]], "b", "blah")) }) test_that("xml_set_attrs works identically to xml_attrs<-", { content <- "" x <- read_xml(content) y <- read_xml(content) xml_attrs(x) <- c(a = "test") xml_set_attrs(y, c(a = "test")) expect_equal(as.character(x), as.character(y)) bx <- xml_find_all(x, "//b") by <- xml_find_all(y, "//b") xml_attrs(bx) <- c(b = "test2") xml_set_attrs(by, c(b = "test2")) expect_equal(as.character(x), as.character(y)) # No errors for xml_missing mss <- xml_find_first(bx, "./c") expect_no_error(xml_attrs(mss[[2]]) <- c("b" = "blah")) expect_no_error(xml_set_attrs(mss[[2]], c("b" = "blah"))) }) test_that("xml_set_attr can set the same namespace multiple times", { doc <- xml_new_root("foo") xml_set_attr(doc, "xmlns:bar", "http://a/namespace") xml_set_attr(doc, "xmlns:bar", "http://b/namespace") expect_equal(xml_attr(doc, "xmlns:bar"), "http://b/namespace") }) xml2/tests/testthat/records.dtd0000644000176200001440000000024214727652467016316 0ustar liggesusers xml2/tests/testthat/test-xml_text.R0000644000176200001440000000401414727652467017125 0ustar liggesuserstest_that("xml_text returns only text without markup", { x <- read_xml("

This is some text. This is bold!

") expect_identical(xml_text(x), "This is some text. This is bold!") expect_identical(xml_text(xml_children(x)), "bold!") }) test_that("xml_text works properly with xml_nodeset objects", { x <- read_xml("

Some text.

Some other.

No bold text

") children <- xml_children(x) x <- xml_find_first(children, ".//b|.//i") expect_identical( xml_text(x), c("text", "other", NA) ) }) test_that("xml_text<- and xml_set_text work properly with xml_nodeset objects", { x <- read_xml("This is some text. This is some nested text.") expect_identical(xml_text(x), "This is some text. This is some nested text.") xml_text(x) <- "test" expect_identical(xml_text(x), "testThis is some nested text.") xml_set_text(x, "test2") expect_identical(xml_text(x), "test2This is some nested text.") }) test_that("xml_text trims whitespace if requested, including non-breaking spaces", { x <- read_html("

Some text €  

") expect_identical( xml_text(x), " Some text \u20ac \u00a0" ) expect_identical( xml_text(x, trim = TRUE), "Some text \u20ac" ) x2 <- read_html("

Some text €  

and more € text  ") expect_identical( xml_text(xml_find_all(x2, ".//p"), trim = TRUE), c("Some text \u20ac", "and more \u20ac text") ) }) test_that("xml_integer() returns an integer vector", { x <- read_xml("") expect_identical( xml_integer(xml_find_all(x, "//@x")), c(1L, 2L) ) }) test_that("xml_double() returns a numeric vector", { x <- read_xml("") expect_identical(xml_double(xml_find_all(x, "//@latitude")), c(42.3466456, -36.8523378)) }) xml2/tests/testthat/test-xml_nodeset.R0000644000176200001440000000532014727652467017603 0ustar liggesuserstest_that("methods work on empty nodesets", { x <- read_xml("") empty <- xml_find_all(x, "//c") expect_error(empty[[1]], "subscript out of bounds") expect_identical(empty[1], empty) test <- empty xml_attr(test, "test") <- 1 expect_identical(test, empty) xml_attrs(test) <- c("test" = 1) expect_identical(test, empty) xml_name(test) <- "test" expect_identical(test, empty) xml_text(test) <- "test" expect_identical(test, empty) expect_identical(as.character(empty), character(0)) expect_identical(as_list(empty), list()) expect_identical(nodeset_apply(empty, identical), empty) expect_output(print(empty), "\\{xml_nodeset \\(0\\)\\}") expect_silent(tree_structure(empty)) xml_add_child(test, "test") expect_identical(test, empty) xml_add_sibling(test, "test") expect_identical(test, empty) expect_identical(xml_attr(empty, "test"), character()) expect_identical(xml_attrs(empty), list()) expect_identical(xml_double(empty), numeric()) expect_identical(xml_find_all(empty), empty) expect_identical(xml_find_chr(empty), character()) expect_identical(xml_find_first(empty), empty) expect_identical(xml_find_lgl(empty), logical()) expect_identical(xml_find_num(empty), numeric()) expect_identical(xml_integer(empty), integer()) expect_identical(xml_length(empty), 0L) expect_identical(xml_name(empty), character()) expect_identical(xml_ns(empty), character()) expect_identical(xml_parent(empty), empty) expect_identical(xml_path(empty), character()) xml_remove(test) expect_identical(test, empty) xml_replace(test) expect_identical(test, empty) xml_set_attr(test, "test", 1) expect_identical(test, empty) xml_set_attrs(test, c("test" = 1)) expect_identical(test, empty) xml_set_name(test, "test") expect_identical(test, empty) xml_set_text(test, "test") expect_identical(test, empty) expect_identical(xml_siblings(empty), empty) expect_silent(xml_structure(empty)) expect_identical(xml_text(empty), character()) expect_identical(xml_url(empty), character()) }) test_that("print method is correct", { skip_if(getOption("width") < 20L, "Screen too narrow") x <- read_html(test_path("lego.html.bz2")) body <- xml_find_first(x, "//body") divs <- xml_find_all(body, ".//div")[1:10] expect_snapshot(print(divs)) # double-substring() logic s <- c( "123456789\\", # always too wide, '\' never encoded "12345", # always fits "12\\45" # doesn't fit when '\' is encoded ) # embed as text on nodes ,, s <- sprintf("<%1$s>%2$s", letters[1:3], s) x <- read_xml(sprintf("%s", paste(s, collapse=""))) expect_snapshot({ print(x, width = 13L) print(x, width = 14L) }) }) xml2/tests/testthat/test-xml_missing.R0000644000176200001440000000276614727652467017626 0ustar liggesusersx <- read_xml("

Some text.

Some other.

No bold text

") para <- xml_find_all(x, ".//p") b <- xml_find_first(para, ".//b") mss <- b[[3]] test_that("xml_find returns nodes of class 'xml_missing' for missing nodes", { expect_length(b, 3L) expect_equal(lengths(b), c(2L, 2L, 0L)) expect_s3_class(mss, "xml_missing") }) test_that("xml_missing methods return properly for all S3 methods", { expect_equal(as.character(mss), NA_character_) expect_equal(as_list(mss), list()) expect_equal(nodeset_apply(mss), xml_nodeset()) expect_output(print(mss), "\\{xml_missing\\}\n") expect_equal(tree_structure(mss), NA_character_) expect_error(write_xml(mss), "Missing data cannot be written") expect_error(write_html(mss), "Missing data cannot be written") expect_equal(xml_attr(mss, "dummy_attr"), NA_character_) expect_equal(xml_attrs(mss), NA_character_) expect_equal(xml_find_all(mss), xml_nodeset()) expect_equal(xml_find_chr(mss), character()) expect_equal(xml_find_lgl(mss), logical()) expect_equal(xml_find_num(mss), numeric()) expect_equal(xml_find_first(mss), xml_missing()) expect_equal(xml_length(mss), 0L) expect_equal(xml_name(mss), NA_character_) expect_equal(xml_parent(mss), xml_missing()) expect_equal(xml_path(mss), NA_character_) expect_equal(xml_text(mss), NA_character_) expect_equal(xml_url(mss), NA_character_) }) test_that("is.na() should return TRUE for xml_missing", { expect_true(is.na(xml_missing())) }) xml2/tests/testthat/test-xml_type.R0000644000176200001440000000071414727652467017125 0ustar liggesuserstest_that("xml_type() works", { x <- read_xml("

Some text.

Some other.

No bold text

") children <- xml_children(x) x <- xml_find_first(children, ".//b|.//i") expect_equal(xml_type(x[[1]]), "element") expect_equal(xml_type(x[[3]]), NA_character_) expect_equal(xml_type(x), c("element", "element", NA)) empty <- xml_children(x) expect_identical(xml_type(empty), character()) }) xml2/tests/testthat/test-as_xml_document.R0000644000176200001440000000230114727652467020437 0ustar liggesusersroundtrip_xml <- function(x) { xml <- read_xml(x) lst <- as_list(xml) xml2 <- as_xml_document(lst) expect_equal(as.character(xml), as.character(xml2)) } test_that("roundtrips with single children", { roundtrip_xml("
") roundtrip_xml("") roundtrip_xml("foo") roundtrip_xml("foobar") roundtrip_xml("foobar") }) test_that("roundtrips with multi children", { roundtrip_xml("") roundtrip_xml("") roundtrip_xml("foobar") roundtrip_xml("foobarbaz") roundtrip_xml("foobar") roundtrip_xml("foobarbaz") }) test_that("rountrips with special attributes", { roundtrip_xml("") }) test_that("more than one root node is an error", { expect_error(as_xml_document(list(a = list(), b = list())), "Root nodes must be of length 1") }) test_that("Can convert nodes with leading and trailing text", { roundtrip_xml("foobarbaz") }) xml2/tests/testthat/test-xml_url.R0000644000176200001440000000454014727652467016747 0ustar liggesuserstest_that("url_absolute", { expect_equal( url_absolute(c(".", "..", "/", "/x"), "http://hadley.nz/a/b/c/d"), c("http://hadley.nz/a/b/c/", "http://hadley.nz/a/b/", "http://hadley.nz/", "http://hadley.nz/x") ) expect_error( url_absolute(c(".", "..", "/", "/x"), c("http://hadley.nz/a/b/c/d", "http://foo.bar")), "Base URL must be length 1" ) }) test_that("url_relative", { # The behavior of libxml2 with relative paths is fragile so we skip this test skip("libxml2-dependent") expect_equal( url_relative("http://hadley.nz/a/c", "http://hadley.nz"), "/a/c" ) expect_equal( url_relative("http://hadley.nz/a/c", "http://hadley.nz/"), "a/c" ) expect_equal( url_relative("http://hadley.nz/a/c", "http://hadley.nz/a/b"), "c" ) expect_equal( url_relative("http://hadley.nz/a/c", "http://hadley.nz/a/b/"), "../c" ) expect_error( url_relative("http://hadley.nz/a/c", c("http://hadley.nz/a/b/c/d", "http://foo.bar")), "Base URL must be length 1" ) }) test_that("url_parse", { expect_equal( url_parse("http://had.co.nz/"), data.frame( scheme = "http", server = "had.co.nz", port = NA_integer_, user = "", path = "/", query = "", fragment = "", stringsAsFactors = FALSE ) ) expect_equal( url_parse("http://had.co.nz:1234/"), data.frame( scheme = "http", server = "had.co.nz", port = 1234L, user = "", path = "/", query = "", fragment = "", stringsAsFactors = FALSE ) ) expect_equal( url_parse("http://had.co.nz:1234/?a=1&b=2"), data.frame( scheme = "http", server = "had.co.nz", port = 1234L, user = "", path = "/", query = "a=1&b=2", fragment = "", stringsAsFactors = FALSE ) ) expect_equal( url_parse("http://had.co.nz:1234/?a=1&b=2#def"), data.frame( scheme = "http", server = "had.co.nz", port = 1234L, user = "", path = "/", query = "a=1&b=2", fragment = "def", stringsAsFactors = FALSE ) ) }) test_that("url_escape", { expect_error( url_escape("a b c", reserved = c("a", "b")), "`reserved` must be character vector of length 1" ) expect_equal( url_escape("a b c"), "a%20b%20c" ) expect_equal( url_escape("a b c", " "), "a b c" ) expect_equal( url_unescape("a%20b%2fc"), "a b/c" ) expect_equal( url_unescape("%C2%B5"), "\u00B5" ) }) xml2/tests/testthat/helper.R0000644000176200001440000000015014727652467015560 0ustar liggesusersmaybe_error <- function(code, ...) { tryCatch(code, error = function(e) expect_error(stop(e), ...)) } xml2/tests/testthat/test-xml_find.R0000644000176200001440000001267514727652467017075 0ustar liggesusers# Find one --------------------------------------------------------------------- test_that("xml_find_first returns a missing object if no match", { x <- read_xml("") expect_equal(xml_find_first(x, ".//z"), xml_missing()) }) test_that("xml_find_first returns the first match if more than one match", { x <- read_xml("") y <- xml_find_first(x, ".//y") expect_s3_class(y, "xml_node") }) test_that("xml_find_first does not deduplicate identical results", { x <- read_xml("") y <- xml_find_all(x, ".//y") z <- xml_find_first(y, "..") expect_s3_class(z, "xml_nodeset") expect_length(z, 2) }) # Find all --------------------------------------------------------------------- test_that("unqualified names don't look in default ns", { x <- read_xml(test_path("ns-multiple-default.xml")) expect_length(xml_find_all(x, "//bar"), 0) }) test_that("qualified names matches to namespace", { x <- read_xml(test_path("ns-multiple-default.xml")) ns <- xml_ns(x) expect_length(xml_find_all(x, "//d1:bar", ns), 1) expect_length(xml_find_all(x, "//d2:bar", ns), 1) }) test_that("warning if unknown namespace", { x <- read_xml("") maybe_error( expect_warning(xml_find_all(x, "//g:bar"), "Undefined namespace prefix"), "evaluation failed" ) }) test_that("no matches returns empty nodeset", { x <- read_xml("") expect_length(xml_find_all(x, "//baz"), 0) }) test_that("xml_find_all returns nodeset or list of nodesets based on flatten", { x <- read_xml("

Some text.

Some other text.

No bold here!

") y <- xml_find_all(x, ".//p") z <- xml_find_all(y, ".//b", flatten = FALSE) expect_s3_class(xml_find_all(y, ".//b"), "xml_nodeset") expect_type(z, "list") expect_s3_class(z[[1L]], "xml_nodeset") }) # Find num --------------------------------------------------------------------- test_that("xml_find_num errors with non numeric results", { x <- read_xml("") expect_snapshot(error = TRUE, { xml_find_num(x, "//z") xml_find_num(x, "//y") xml_find_num(x, "1=1") xml_find_num(x, "string(5)") }) }) test_that("xml_find_num returns a numeric result", { x <- read_xml("1") expect_equal(xml_find_num(x, "1 div 0"), Inf) expect_equal(xml_find_num(x, "-1 div 0"), -Inf) expect_equal(xml_find_num(x, "0 div 0"), NaN) expect_equal(xml_find_num(x, "1 div floor(-0.1)"), -1) expect_equal(xml_find_num(x, "1 div floor(0)"), Inf) expect_equal(xml_find_num(x, "1 div floor(-0)"), -Inf) }) # Find int --------------------------------------------------------------------- test_that("xml_find_int errors with non integer results", { x <- read_xml("") expect_snapshot(error = TRUE, { xml_find_int(x, "//z") xml_find_int(x, "//y") xml_find_int(x, "number(1.1)") }) }) test_that("xml_find_int returns a integer result", { x <- read_xml("1") expect_identical(xml_find_int(x, "1 div floor(-0.1)"), -1L) expect_identical(xml_find_int(x, "number(//y)"), 1L) expect_identical(xml_find_int(x, "string-length(string('abcd'))"), 4L) }) # Find chr --------------------------------------------------------------------- test_that("xml_find_chr errors with non character results", { x <- read_xml("") expect_snapshot(error = TRUE, { xml_find_chr(x, "//z") xml_find_chr(x, "//y") xml_find_chr(x, "1=1") xml_find_chr(x, "1+1") }) }) test_that("xml_find_chr returns a character result", { x <- read_xml("1") expect_equal(xml_find_chr(x, "string(5)"), "5") expect_equal(xml_find_chr(x, "string(0.5)"), "0.5") expect_equal(xml_find_chr(x, "string(-0.5)"), "-0.5") expect_equal(xml_find_chr(x, "concat(\"titi\", \"toto\")"), "tititoto") expect_equal(xml_find_chr(x, "substring(\"12345\", 2, 3)"), "234") expect_equal(xml_find_chr(x, "substring(\"12345\", 2)"), "2345") expect_equal(xml_find_chr(x, "substring(\"12345\", -4)"), "12345") }) # Find lgl --------------------------------------------------------------------- test_that("xml_find_lgl errors with non logical results", { x <- read_xml("") expect_snapshot(error = TRUE, { xml_find_lgl(x, "//z") xml_find_lgl(x, "//y") xml_find_lgl(x, "string(5)") xml_find_lgl(x, "1+1") }) }) test_that("xml_find_lgl returns a logical result", { x <- read_xml("1") expect_true(xml_find_lgl(x, "1=1")) expect_false(xml_find_lgl(x, "1!=1")) expect_true(xml_find_lgl(x, "true()=true()")) expect_false(xml_find_lgl(x, "true()=false()")) expect_true(xml_find_lgl(x, "'test'='test'")) }) test_that("Searches with empty inputs retain type stability", { empty <- xml_nodeset() expect_equal(xml_find_num(empty, "1 div 0"), integer()) expect_equal(xml_find_chr(empty, "string(0.5)"), character()) expect_equal(xml_find_lgl(empty, "1=1"), logical()) }) test_that("Searches with entities work (#241)", { res <- read_xml(test_path("records.xml"), options = "DTDVALID") field1 <- xml_find_all(res, "//field1") expect_equal(xml_text(field1), "foo bar Quantitative Consultancy") }) test_that("A helpful error is given from non-string xpath in xml_find_first/all", { node <- read_xml("1") expect_error(xml_find_all(node, 1), "XPath must be a string", fixed = TRUE) expect_error(xml_find_first(node, 1), "XPath must be a string", fixed = TRUE) }) xml2/tests/testthat/ns-multiple.xml0000644000176200001440000000020714727652467017154 0ustar liggesusers xml2/tests/testthat/test-xml_parse.R0000644000176200001440000000612614727652467017261 0ustar liggesuserstest_that("download_xml fails if curl is not installed", { skip("how to test error with `check_installed()`?") mockery::stub(download_xml, "requireNamespace", function(...) FALSE) expect_error( download_xml("http://httpbin.org/xml"), "`curl` must be installed to use `download_xml\\(\\)`" ) }) test_that("read_xml errors with an empty document", { expect_snapshot(error = TRUE, { read_xml(character()) }) tf <- tempfile() file.create(tf) on.exit(unlink(tf)) expect_error(read_xml(tf), "Document is empty") }) test_that("read_html correctly parses malformed document", { lego <- read_html(test_path("lego.html.bz2")) expect_length(xml_find_all(lego, ".//p"), 39) }) test_that("parse_options errors when given an invalid option", { expect_error( parse_options("INVALID", xml_parse_options()), '`options` "INVALID" is not a valid option' ) expect_snapshot(error = TRUE, read_html(test_path("lego.html.bz2"), options = "INVALID") ) # Empty inputs returned as 0 expect_identical(0L, parse_options("", xml_parse_options())) expect_identical(0L, parse_options(NULL, xml_parse_options())) # Numerics returned as integers expect_identical(12L, parse_options(12L, xml_parse_options())) expect_identical(12L, parse_options(12, xml_parse_options())) # Multiple inputs summed expect_identical(3L, parse_options(c("RECOVER", "NOENT"), xml_parse_options())) }) test_that("read_html properly passes parser arguments", { skip_if_not(libxml2_version() >= "2.9.2") blanks <- read_html(xml2_example("cd_catalog.xml"), options = c("RECOVER", "NOERROR")) expect_equal( as_list(blanks)$html$body$catalog$cd[[1]], "\r\n " ) no_blanks <- read_html(xml2_example("cd_catalog.xml"), options = c("RECOVER", "NOERROR", "NOBLANKS")) expect_equal( as_list(no_blanks)$html$body$catalog$cd[[1]], list("Empire Burlesque") ) }) test_that("read_xml works with httr response objects", { skip("httpbin is unreliable") x <- read_xml(httr::GET("http://httpbin.org/xml")) expect_s3_class(x, "xml_document") expect_length(xml_find_all(x, "//slide"), 2) }) test_that("read_xml and read_html fail for bad status codes", { skip("httpbin is unreliable") expect_error( read_xml(httr::GET("http://httpbin.org/status/404")), class = "http_404" ) expect_error( read_html(httr::GET("http://httpbin.org/status/404")), class = "http_404" ) }) test_that("read_xml works with raw inputs", { x <- read_xml("") expect_equal(xml_url(x), NA_character_) }) test_that("read_html works with non-ASCII encodings", { tmp <- tempfile() on.exit(unlink(tmp)) writeLines("\U2019", tmp, useBytes = TRUE) res <- read_html(tmp, encoding = "UTF-8") expect_equal( as.character(res, options = ""), "\n\U2019\n" ) }) test_that("read_xml and read_html fail with > 1 input", { expect_snapshot(error = TRUE, { read_xml(c("foo", "bar")) read_html(c("foo", "bar")) }) }) xml2/tests/testthat/test-xml_modify.R0000644000176200001440000001626214727652467017440 0ustar liggesuserstest_that("modifying nodes works", { x <- read_xml("") node <- xml_find_first(x, "//x") expect_equal(xml_name(node), "x") .Call(node_set_name, node$node, "y") expect_equal(xml_name(node), "y") expect_equal(xml_text(node), "") .Call(node_set_content, node$node, "test") expect_equal(xml_text(node), "test") }) test_that("xml_text<- only modifies text content", { x <- read_xml("Text1text2") expect_equal(xml_text(x), "Text1text2") # will only change the first text by default xml_text(x) <- "new_text1" expect_equal(xml_text(x), "new_text1text2") # You can change the second by explicitly selecting it text_node <- xml_find_first(x, "//text()[2]") xml_text(text_node) <- "new_text2" expect_equal(xml_text(x), "new_text1new_text2") }) test_that("xml_text<- creates new text nodes if needed", { x <- read_xml("") xml_text(x) <- "test" expect_equal(xml_text(x), "test") }) test_that("xml_remove removes nodes", { x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] xml_remove(children, free = TRUE) expect_equal(xml_text(x), "") }) test_that("xml_replace replaces nodes", { x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] t2 <- children[[2]] t3 <- xml_children(children[[2]])[[1]] expect_equal(xml_text(x), "123") xml_replace(t1, t3) expect_equal(xml_text(x), "323") first_child <- xml_children(x)[[1]] xml_replace(first_child, t1, .copy = FALSE) expect_equal(xml_text(x), "123") xml_remove(first_child, free = TRUE) first_child <- xml_children(x)[[1]] xml_replace(first_child, t3, .copy = FALSE) expect_equal(xml_text(x), "32") xml_remove(first_child, free = TRUE) }) test_that("xml_replace works with nodesets", { x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] xml_replace(children, t1) expect_equal(xml_text(x), "11") }) test_that("xml_sibling adds a sibling node", { x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] t2 <- children[[2]] t3 <- xml_children(children[[2]])[[1]] xml_add_sibling(t1, t3) expect_length(xml_siblings(t1), 2) expect_equal(xml_text(x), "1323") xml_add_sibling(t1, t3, .where = "before") expect_length(xml_siblings(t1), 3) expect_equal(xml_text(x), "31323") children <- xml_children(x) xml_add_sibling(children, t1) expect_equal(xml_text(x), "311131231") }) test_that("xml_add_child adds a child node", { x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] t2 <- children[[2]] t3 <- xml_children(children[[2]])[[1]] expect_length(xml_children(t1), 0) xml_add_child(t1, t3, .copy = TRUE) expect_length(xml_children(t1), 1) expect_equal(xml_text(x), "1323") children <- xml_children(x) xml_add_child(children, t1) expect_equal(xml_text(x), "1313231313") }) test_that("xml_add_child can create a new default namespace", { x <- xml_root(xml_add_child(xml_new_document(), "foo", xmlns = "bar")) expect_equal(unclass(xml_ns(x)), c(d1 = "bar")) }) test_that("xml_add_child can create a new prefixed namespace", { x <- xml_root(xml_add_child(xml_new_document(), "foo", "xmlns:bar" = "baz")) expect_equal(unclass(xml_ns(x)), c(bar = "baz")) }) test_that("xml_add_child can create a new attribute", { x <- xml_add_child(xml_new_document(), "foo", "bar" = "baz") expect_equal(xml_attr(x, "bar"), "baz") }) test_that("xml_add_child can create new text", { x <- xml_add_child(xml_new_document(), "foo", "bar") expect_equal(xml_text(x), "bar") }) test_that("xml_add_child can create a new node with the specified prefix", { x <- xml_root(xml_add_child(xml_new_document(), "foo", "xmlns:bar" = "baz")) t1 <- xml_add_child(x, "bar:qux") expect_equal(xml_name(t1), "qux") expect_equal(xml_name(t1, xml_ns(x)), "bar:qux") }) test_that("xml_add_child can create a new node with the specified prefix", { x <- xml_root(xml_add_child(xml_new_document(), "foo", "xmlns:bar" = "baz")) expect_error(xml_add_child(x, "bar2:qux"), "No namespace with prefix `bar2` found") }) # https://github.com/r-lib/xml2/issues/284 test_that("xml_add_child can create a new node with attribute named 'par'", { x <- xml_new_root("foo") t1 <- xml_add_child(x, "a", "par" = "b") expect_true(xml_has_attr(t1, "par")) }) test_that("xml_add_parent works with xml_node input", { x <- read_xml("") y <- xml_find_first(x, ".//y") xml_add_parent(y, "z") expect_equal(xml_name(xml_parent(y)), "z") expect_equal(xml_name(xml_child(x)), "z") }) test_that("xml_add_parent works with xml_nodeset input", { x <- read_xml("") y <- xml_find_all(x, ".//y") xml_add_parent(y, "z") expect_equal(xml_name(xml_parent(y)), c("z", "z")) expect_equal(xml_name(xml_child(x)), "z") }) test_that("xml_add_parent works with xml_missing input", { x <- read_xml("

Some text.

Some other.

No bold text

") y <- xml_find_all(x, ".//p") z <- xml_find_first(y, ".//b") xml_add_parent(z, "em") expect_equal(xml_name(xml_parent(z)), c("em", "em")) expect_equal(xml_name(xml_children(y)), c("em", "em")) }) test_that("xml_new_document adds a default character encoding", { x <- read_xml("\u00E1\u00FC\u00EE") expect_equal(as.character(x), "\n\u00E1\u00FC\u00EE\n") x2 <- xml_new_document() xml_add_child(x2, "root", "\u00E1\u00FC\u00EE") expect_equal(as.character(x2), "\n\u00E1\u00FC\u00EE\n") }) test_that("xml_new_root is equivalent to using xml_new_document xml_add_child", { x1 <- xml_add_child(xml_new_document(), "foo", "bar") x2 <- xml_new_root("foo", "bar") expect_identical(as.character(x1), as.character(x2)) }) test_that("xml_add_child can insert anywhere in the child list", { x <- read_xml("") xml_add_child(x, "z") expect_equal(c("z"), xml_name(xml_children(x))) xml_add_child(x, "w", .where = 0) expect_equal(c("w", "z"), xml_name(xml_children(x))) xml_add_child(x, "y", .where = 1) expect_equal(c("w", "y", "z"), xml_name(xml_children(x))) xml_add_child(x, "x", .where = 1) expect_equal(c("w", "x", "y", "z"), xml_name(xml_children(x))) }) test_that("xml_add_child can insert anywhere in a nodeset", { x <- read_xml("

Some text.

Some other.

No bold text

") y <- xml_find_all(x, ".//p") z <- xml_find_first(y, ".//b") xml_add_child(z, "bar") xml_add_child(z, "foo", .where = 0) expect_equal(c("foo", "bar", "foo", "bar"), xml_name(xml_children(z))) }) test_that("Can write root nodes with namespaces", { x <- xml_new_root("foo:bar", "xmlns:foo" = "http://foo/bar") expect_equal(unclass(xml_ns(x)), c(foo = "http://foo/bar")) expect_equal(as.character(xml_find_first(x, "/*")), "") }) xml2/tests/testthat/test-xml_children.R0000644000176200001440000000274214727652467017737 0ustar liggesusersx <- read_xml(" ") test_that("xml_child() returns the proper child", { expect_identical(xml_child(x), xml_children(x)[[1L]]) expect_identical(xml_child(x, 2), xml_children(x)[[2L]]) }) test_that("xml_child() returns child by name", { expect_identical(xml_child(x, "baz"), xml_find_first(x, "./baz")) }) test_that("xml_child() errors if more than one search is given", { expect_snapshot(error = TRUE, xml_child(x, 1:2)) }) test_that("xml_child() errors if search is not numeric or character", { expect_error(xml_child(x, TRUE), "`search` must be `numeric` or `character`") expect_error(xml_child(x, as.factor("test")), "`search` must be `numeric` or `character`") expect_error(xml_child(x, raw(1)), "`search` must be `numeric` or `character`") expect_error(xml_child(x, list(1)), "`search` must be `numeric` or `character`") }) test_that("xml_length", { expect_equal(xml_length(x), 2) all <- xml_find_all(x, "//*") expect_equal(xml_length(all), c(2, 1, 0, 0)) }) test_that("xml_parent", { expect_identical(unclass(xml_parent(xml_child(x))), unclass(x)) }) test_that("xml_parents", { expect_equal( xml_name(xml_parents(xml_find_first(x, "//boo"))), c("bar", "foo") ) }) test_that("xml_root", { doc <- xml_new_document() expect_s3_class(xml_root(doc), "xml_missing") a <- xml_add_child(doc, "a") b <- xml_add_child(doc, "b") expect_equal(xml_name(xml_root(b)), "a") expect_equal(xml_name(xml_root(doc)), "a") }) xml2/tests/testthat/test-xml_schema.R0000644000176200001440000000135614727652467017407 0ustar liggesuserstest_that("xml schema validates", { doc <- read_xml(system.file("extdata/order-doc.xml", package = "xml2")) schema <- read_xml(system.file("extdata/order-schema.xml", package = "xml2")) expect_true(xml_validate(doc, schema)) }) test_that("xml schema errors", { str <- readLines(system.file("extdata/order-doc.xml", package = "xml2")) str <- sub("1", "", str) str <- sub("95819", "ABC95819", str) str <- sub('partNum="926-AA"', "", str) doc <- read_xml(paste(str, collapse = "\n")) schema <- read_xml(system.file("extdata/order-schema.xml", package = "xml2")) out <- xml_validate(doc, schema) expect_false(out) errors <- attr(out, "errors") expect_type(errors, "character") expect_length(errors, 4) }) xml2/tests/testthat/test-xml_write.R0000644000176200001440000000747714727652467017313 0ustar liggesuserstest_that("write_xml errors for incorrect directory and with invalid inputs", { x <- read_xml("") filename <- "does_not_exist/test.xml" expect_error(write_xml(x, filename), "'does_not_exist' does not exist in current working directory") expect_snapshot(error = TRUE, { write_xml(x, c("test.xml", "foo")) }) }) test_that("write_xml works with relative file paths", { x <- read_xml("") filename <- "../test.xml" on.exit(unlink(filename)) write_xml(x, filename, options = "no_declaration") expect_identical(readChar(filename, 1000L), "\n") }) test_that("write_xml works with no options", { x <- read_xml("") filename <- "../test.xml" on.exit(unlink(filename)) write_xml(x, filename, options = NULL) expect_identical(readChar(filename, 1000L), "\n\n") }) test_that("write_xml works with an explicit connections", { x <- read_xml("") filename <- "../test.xml" file <- file(filename, "wb") on.exit(unlink(filename)) write_xml(x, file, options = "no_declaration") close(file) expect_identical(readChar(filename, 1000L), "\n") }) test_that("write_xml works with an implicit connections", { x <- read_xml("") filename <- "../test.xml.gz" write_xml(x, filename, options = "no_declaration") file <- gzfile(filename, "rb") on.exit({ unlink(filename) close(file) }) expect_identical(readChar(file, 1000L), "\n") }) test_that("write_xml works with nodeset input and files", { x <- read_xml("") y <- xml_find_all(x, "//y") filename <- "../test.xml" on.exit(unlink(filename)) expect_error( write_xml(y, filename, options = "no_declaration"), "Can only save length 1 node sets" ) write_xml(y[1], filename, options = "no_declaration") expect_identical(readChar(filename, 1000L), "") }) test_that("write_xml works with nodeset input and connections", { x <- read_xml("") y <- xml_find_all(x, "//y") filename <- "../test.xml.gz" expect_error( write_xml(y, filename, options = "no_declaration"), "Can only save length 1 node sets" ) expect_snapshot(error = TRUE, { write_xml(y[1], c(filename, "foo")) }) write_xml(y[1], filename, options = "no_declaration") file <- gzfile(filename, "rb") on.exit({ unlink(filename) close(file) }) expect_identical(readChar(file, 1000L), "") }) test_that("write_xml works with node input and files", { x <- read_xml("") y <- xml_find_first(x, "//y") filename <- "../test.xml" expect_snapshot(error = TRUE, write_xml(y, c(filename, "foo"))) write_xml(y, filename, options = "no_declaration") on.exit(unlink(filename)) expect_identical(readChar(filename, 1000L), "") }) test_that("write_xml works with node input and connections", { x <- read_xml("") y <- xml_find_first(x, "//y") filename <- "../test.xml.gz" write_xml(y, filename, options = "no_declaration") file <- gzfile(filename, "rb") on.exit({ unlink(filename) close(file) }) expect_identical(readChar(file, 1000L), "") }) test_that("write_html work with html input", { x <- read_html("Foo") filename <- "../test.html.gz" write_html(x, filename) file <- gzfile(filename, "rb") on.exit({ unlink(filename) close(file) }) expect_identical( readChar(file, 1000L), "\n\n\nFoo\n\n" ) }) test_that("write_xml returns invisibly", { x <- read_xml("foo") tf <- tempfile() on.exit(unlink(tf)) res <- withVisible(write_xml(x, tf)) expect_null(res$value) expect_false(res$visible) }) xml2/tests/testthat/test-xml_namespaces.R0000644000176200001440000000263514727652467020267 0ustar liggesusers# XML parsing tests ------------------------------------------------------------ test_that("multiple default namespaces given unique names", { ns <- unclass(xml_ns(read_xml(test_path("ns-multiple-default.xml")))) expect_equal(ns, c(d1 = "http://foo.com", d2 = "http://bar.com")) }) test_that("repeated prefixes given unique names", { ns <- unclass(xml_ns(read_xml(test_path("ns-multiple-prefix.xml")))) expect_equal(ns, c(b = "http://baz.com", b1 = "http://bar.com")) }) test_that("aliased prefixes retained", { ns <- unclass(xml_ns(read_xml(test_path("ns-multiple-aliases.xml")))) expect_equal(ns, c(b = "http://bar.com", c = "http://bar.com")) }) # Low-level character vector tests --------------------------------------------- test_that("unique prefix-url combo unchanged", { x <- c(blah = "http://blah.com", rah = "http://rah.com") expect_equal(.Call(unique_ns, x), x) }) test_that("all prefixs kept", { x <- c(blah = "http://blah.com", rah = "http://blah.com") expect_named(.Call(unique_ns, x), c("blah", "rah")) }) test_that("multiple default namespaces can be stripped", { x <- read_xml(test_path("ns-multiple-default.xml")) ns <- unclass(xml_ns(x)) expect_equal(ns, c(d1 = "http://foo.com", d2 = "http://bar.com")) expect_length(xml_find_all(x, "//bar"), 0) xml_ns_strip(x) ns <- unclass(xml_ns(x)) expect_equal(unname(ns), character()) expect_length(xml_find_all(x, "//bar"), 2) }) xml2/tests/testthat/test-classes.R0000644000176200001440000000331314727652467016717 0ustar liggesuserstest_that("CDATA creation works", { x <- xml_new_root("root") xml_add_child(x, xml_cdata("")) expect_identical(as.character(x), "\n]]>\n") }) test_that("Comment creation works", { x <- xml_new_root("root") xml_add_child(x, xml_comment("Hello!")) expect_identical("\n\n", as.character(x, options = "")) }) test_that("xml_dtd works", { r <- xml_new_root(xml_dtd(name = "html", external_id = "-//W3C//DTD XHTML 1.0 Transitional//EN", system_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")) expect_identical("\n\n", as.character(r)) no_name <- xml_new_root(xml_dtd(external_id = "-//W3C//DTD XHTML 1.0 Transitional//EN", system_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")) expect_identical("\n\n", as.character(no_name)) no_name_external_id <- xml_new_root(xml_dtd(system_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")) expect_identical("\n\n", as.character(no_name_external_id)) no_name_external_id_internal_id <- xml_new_root(xml_dtd()) expect_identical("\n\n", as.character(no_name_external_id_internal_id)) }) xml2/tests/testthat/ns-multiple-default.xml0000644000176200001440000000015714727652467020602 0ustar liggesusers xml2/tests/testthat/test-xml_serialize.R0000644000176200001440000000320214727652467020126 0ustar liggesusersx <- read_xml("
123 456 ") test_that("xml_serialize and xml_unserialize work with xml_document input", { out <- xml_unserialize(xml_serialize(x, NULL)) expect_identical(as.character(x), as.character(out)) f <- tempfile() on.exit(unlink(f)) xml_serialize(x, f) expect_identical(as.character(xml_unserialize(f)), as.character(x)) }) test_that("xml_serialize and xml_unserialize work with xml_node input", { b <- xml_find_first(x, "//b") out <- xml_unserialize(xml_serialize(b, NULL)) expect_identical(as.character(b), as.character(out)) f <- tempfile() on.exit(unlink(f)) xml_serialize(b, f) expect_identical(as.character(xml_unserialize(f)), as.character(b)) }) test_that("xml_serialize and xml_unserialize work with xml_nodeset input", { b <- xml_find_all(x, "//b") out <- xml_unserialize(xml_serialize(b, NULL)) expect_identical(as.character(b), as.character(out)) f <- tempfile() on.exit(unlink(f)) xml_serialize(b, f) expect_identical(as.character(xml_unserialize(f)), as.character(b)) }) test_that("xml_serialize and xml_unserialize work with HTML-based xml_document input", { file <- system.file("extdata", "r-project.html", package = "xml2") x <- read_html(file) out <- xml_unserialize(xml_serialize(x, NULL)) expect_identical(as.character(x), as.character(out)) f <- tempfile() on.exit(unlink(f)) xml_serialize(x, f) expect_identical(as.character(xml_unserialize(f)), as.character(x)) }) test_that("xml_unserialize throws an error if given a invalid object", { expect_error(xml_unserialize(serialize(1, NULL)), "Not a serialized xml2 object") }) xml2/tests/testthat/_snaps/0000755000176200001440000000000014727652467015445 5ustar liggesusersxml2/tests/testthat/_snaps/xml_parse.md0000644000176200001440000000206714760705220017745 0ustar liggesusers# read_xml errors with an empty document Code read_xml(character()) Condition Error in `read_xml()`: ! `x` must be a single string, not an empty character vector. # parse_options errors when given an invalid option Code read_html(test_path("lego.html.bz2"), options = "INVALID") Condition Error in `read_html()`: x `options` "INVALID" is not a valid option. i Valid options are one of "RECOVER", "NOENT", "DTDLOAD", "DTDATTR", "DTDVALID", "NOERROR", "NOWARNING", "PEDANTIC", "NOBLANKS", "SAX1", "XINCLUDE", "NONET", "NODICT", "NSCLEAN", "NOCDATA", "NOXINCNODE", "COMPACT", "OLD10", ..., "IGNORE_ENC", or "BIG_LINES". i See read_html (`?xml2::read_html()`) for all options. # read_xml and read_html fail with > 1 input Code read_xml(c("foo", "bar")) Condition Error in `read_xml()`: ! `x` must be a single string, not a character vector. Code read_html(c("foo", "bar")) Condition Error in `read_xml()`: ! `x` must be a single string, not a character vector. xml2/tests/testthat/_snaps/xml_write.md0000644000176200001440000000120314760705221017755 0ustar liggesusers# write_xml errors for incorrect directory and with invalid inputs Code write_xml(x, c("test.xml", "foo")) Condition Error in `write_xml()`: ! `file` must be a single string, not a character vector. # write_xml works with nodeset input and connections Code write_xml(y[1], c(filename, "foo")) Condition Error in `write_xml()`: ! `file` must be a single string, not a character vector. # write_xml works with node input and files Code write_xml(y, c(filename, "foo")) Condition Error in `write_xml()`: ! `file` must be a single string, not a character vector. xml2/tests/testthat/_snaps/xml_structure.md0000644000176200001440000001772314760705220020700 0ustar liggesusers# xml_structure is correct Code html_structure(quicklinks) Output {text}

{text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text}
{text}

{text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text}

{text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text}

{text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text}

{text} {text} {text} {text} {text} {text} {text} {text} {text} {text}

{text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text}

{text} {text} {text} {text} {text} {text}

{text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text} {text}

{text} {text} {text} {text} {text} {text} {text} {text} {text} {text}
{text} {text} {text} {text} {text} xml2/tests/testthat/_snaps/xml_attr.md0000644000176200001440000000026714760705217017613 0ustar liggesusers# xml_attrs<- modifies all attributes Code xml_attrs(docs) <- "test" Condition Error in `xml_attrs<-`: ! `test` must be a list of named character vectors. xml2/tests/testthat/_snaps/xml_find.md0000644000176200001440000000504314760705220017550 0ustar liggesusers# xml_find_num errors with non numeric results Code xml_find_num(x, "//z") Condition Error in `xml_find_num()`: ! Element at path `//z` must be a number, not a object. Code xml_find_num(x, "//y") Condition Error in `xml_find_num()`: ! Element at path `//y` must be a number, not a list. Code xml_find_num(x, "1=1") Condition Error in `xml_find_num()`: ! Element at path `1=1` must be a number, not `TRUE`. Code xml_find_num(x, "string(5)") Condition Error in `xml_find_num()`: ! Element at path `string(5)` must be a number, not the string "5". # xml_find_int errors with non integer results Code xml_find_int(x, "//z") Condition Error in `xml_find_int()`: ! Element at path `//z` must be a whole number, not a object. Code xml_find_int(x, "//y") Condition Error in `xml_find_int()`: ! Element at path `//y` must be a whole number, not a list. Code xml_find_int(x, "number(1.1)") Condition Error in `xml_find_int()`: ! Element at path `number(1.1)` must be a whole number, not the number 1.1. # xml_find_chr errors with non character results Code xml_find_chr(x, "//z") Condition Error in `xml_find_chr()`: ! Element at path `//z` must be a single string, not a object. Code xml_find_chr(x, "//y") Condition Error in `xml_find_chr()`: ! Element at path `//y` must be a single string, not a list. Code xml_find_chr(x, "1=1") Condition Error in `xml_find_chr()`: ! Element at path `1=1` must be a single string, not `TRUE`. Code xml_find_chr(x, "1+1") Condition Error in `xml_find_chr()`: ! Element at path `1+1` must be a single string, not the number 2. # xml_find_lgl errors with non logical results Code xml_find_lgl(x, "//z") Condition Error in `xml_find_lgl()`: ! Element at path `//z` must be `TRUE` or `FALSE`, not a object. Code xml_find_lgl(x, "//y") Condition Error in `xml_find_lgl()`: ! Element at path `//y` must be `TRUE` or `FALSE`, not a list. Code xml_find_lgl(x, "string(5)") Condition Error in `xml_find_lgl()`: ! Element at path `string(5)` must be `TRUE` or `FALSE`, not the string "5". Code xml_find_lgl(x, "1+1") Condition Error in `xml_find_lgl()`: ! Element at path `1+1` must be `TRUE` or `FALSE`, not the number 2. xml2/tests/testthat/_snaps/xml_nodeset.md0000644000176200001440000000224614760705220020273 0ustar liggesusers# print method is correct Code print(divs) Output {xml_nodeset (10)} [1]
\n
\n\n

Node Modification

Jim Hester

2025-03-14

Modifying Existing XML

Modifying existing XML can be done in xml2 by using the replacement functions of the accessors. They all have methods for both individual xml_node objects as well as xml_nodeset objects. If a vector of values is provided it is applied piecewise over the nodeset, otherwise the value is recycled.

Text Modification

Text modification only happens on text nodes. If a given node has more than one text node only the first will be affected. If you want to modify additional text nodes you need to select them explicitly with /text().

x <- read_xml("<p>This is some <b>text</b>. This is more.</p>")
xml_text(x)
#> [1] "This is some text. This is more."

xml_text(x) <- "This is some other text."
xml_text(x)
#> [1] "This is some other text.text. This is more."

# You can avoid this by explicitly selecting the text node.
x <- read_xml("<p>This is some text. This is <b>bold!</b></p>")
text_only <- xml_find_all(x, "//text()")

xml_text(text_only) <- c("This is some other text. ", "Still bold!")
xml_text(x)
#> [1] "This is some other text. Still bold!"
xml_structure(x)
#> <p>
#>   {text}
#>   <b>
#>     {text}

Attribute and Namespace Definition Modification

Attributes and namespace definitions are modified one at a time with xml_attr() or all at once with xml_attrs(). In both cases using NULL as the value will remove the attribute completely.

x <- read_xml("<a href='invalid!'>xml2</a>")
xml_attr(x, "href")
#> [1] "invalid!"

xml_attr(x, "href") <- "https://github.com/r-lib/xml2"
xml_attr(x, "href")
#> [1] "https://github.com/r-lib/xml2"

xml_attrs(x) <- c(id = "xml2", href = "https://github.com/r-lib/xml2")
xml_attrs(x)
#>                            href                              id 
#> "https://github.com/r-lib/xml2"                          "xml2"
x
#> {xml_document}
#> <a href="https://github.com/r-lib/xml2" id="xml2">

xml_attrs(x) <- NULL
x
#> {xml_document}
#> <a>

# Namespaces are added with as a xmlns or xmlns:prefix attribute
xml_attr(x, "xmlns") <- "http://foo"
x
#> {xml_document}
#> <a xmlns="http://foo">

xml_attr(x, "xmlns:bar") <- "http://bar"
x
#> {xml_document}
#> <a xmlns="http://foo" xmlns:bar="http://bar">

Name Modification

Node names are modified with xml_name().

x <- read_xml("<a><b/></a>")
x
#> {xml_document}
#> <a>
#> [1] <b/>
xml_name(x)
#> [1] "a"
xml_name(x) <- "c"
x
#> {xml_document}
#> <c>
#> [1] <b/>

Node modification

All of these functions have a .copy argument. If this is set to FALSE they will remove the new node from its location before inserting it into the new location. Otherwise they make a copy of the node before insertion.

Replacing existing nodes

x <- read_xml("<parent><child>1</child><child>2<child>3</child></child></parent>")
children <- xml_children(x)
t1 <- children[[1]]
t2 <- children[[2]]
t3 <- xml_children(children[[2]])[[1]]

xml_replace(t1, t3)
#> {xml_node}
#> <child>
x
#> {xml_document}
#> <parent>
#> [1] <child>3</child>
#> [2] <child>2<child>3</child></child>

Add a sibling

x <- read_xml("<parent><child>1</child><child>2<child>3</child></child></parent>")
children <- xml_children(x)
t1 <- children[[1]]
t2 <- children[[2]]
t3 <- xml_children(children[[2]])[[1]]

xml_add_sibling(t1, t3)
x
#> {xml_document}
#> <parent>
#> [1] <child>1</child>
#> [2] <child>3</child>
#> [3] <child>2<child>3</child></child>

xml_add_sibling(t3, t1, where = "before")
x
#> {xml_document}
#> <parent>
#> [1] <child>1</child>
#> [2] <child>3</child>
#> [3] <child>2<child>3</child><child>1</child></child>

Add a child

x <- read_xml("<parent><child>1</child><child>2<child>3</child></child></parent>")
children <- xml_children(x)
t1 <- children[[1]]
t2 <- children[[2]]
t3 <- xml_children(children[[2]])[[1]]

xml_add_child(t1, t3)
x
#> {xml_document}
#> <parent>
#> [1] <child>1<child>3</child></child>
#> [2] <child>2<child>3</child></child>

xml_add_child(t1, read_xml("<test/>"))
x
#> {xml_document}
#> <parent>
#> [1] <child>1<child>3</child><test/></child>
#> [2] <child>2<child>3</child></child>

Removing nodes

The xml_remove() can be used to remove a node (and its children) from a tree. The default behavior is to unlink the node from the tree, but does not free the memory for the node, so R objects pointing to the node are still valid.

This allows code like the following to work without crashing R

x <- read_xml("<foo><bar><baz/></bar></foo>")
x1 <- x %>%
  xml_children() %>%
  .[[1]]
x2 <- x1 %>%
  xml_children() %>%
  .[[1]]

xml_remove(x1)
rm(x1)
gc()
#>           used (Mb) gc trigger (Mb) limit (Mb) max used (Mb)
#> Ncells  631023 33.8    1423872 76.1         NA  1267757 67.8
#> Vcells 1187491  9.1    8388608 64.0      16384  2646979 20.2

x2
#> {xml_node}
#> <baz>

If you are not planning on referencing these nodes again this memory is wasted. Calling xml_remove(free = TRUE) will remove the nodes and free the memory used to store them. Note In this case any node which previously pointed to the node or its children will instead be pointing to free memory and may cause R to crash. xml2 can’t figure this out for you, so it’s your responsibility to remove any objects which are no longer valid.

In particular xml_find_*() results are easy to overlook, for example

x <- read_xml("<a><b /><b><b /></b></a>")
bees <- xml_find_all(x, "//b")
xml_remove(xml_child(x), free = TRUE)
# bees[[1]] is no longer valid!!!
rm(bees)
gc()
#>           used (Mb) gc trigger (Mb) limit (Mb) max used (Mb)
#> Ncells  631067 33.8    1423872 76.1         NA  1267757 67.8
#> Vcells 1187692  9.1    8388608 64.0      16384  2646979 20.2

Namespaces

We want to construct a document with the following namespace layout. (From https://stackoverflow.com/questions/32939229/creating-xml-in-r-with-namespaces/32941524#32941524).

<?xml version = "1.0" encoding="UTF-8"?>
<sld xmlns="http://www.opengis.net/sld"
     xmlns:ogc="http://www.opengis.net/ogc"
     xmlns:se="http://www.opengis.net/se"
     version="1.1.0" >
<layer>
<se:Name>My Layer</se:Name>
</layer>
</sld>
d <- xml_new_root("sld",
  "xmlns" = "http://www.opengis.net/sld",
  "xmlns:ogc" = "http://www.opengis.net/ogc",
  "xmlns:se" = "http://www.opengis.net//se",
  version = "1.1.0"
) %>%
  xml_add_child("layer") %>%
  xml_add_child("se:Name", "My Layer") %>%
  xml_root()

d
#> {xml_document}
#> <sld version="1.1.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:se="http://www.opengis.net//se">
#> [1] <layer>\n  <se:Name>My Layer</se:Name>\n</layer>
xml2/inst/doc/modification.Rmd0000644000176200001440000001203114727652467016010 0ustar liggesusers--- title: "Node Modification" author: "Jim Hester" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Node Modification} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, echo = FALSE, message = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") library(xml2) library(magrittr) ``` # Modifying Existing XML Modifying existing XML can be done in xml2 by using the replacement functions of the accessors. They all have methods for both individual `xml_node` objects as well as `xml_nodeset` objects. If a vector of values is provided it is applied piecewise over the nodeset, otherwise the value is recycled. ## Text Modification ## Text modification only happens on text nodes. If a given node has more than one text node only the first will be affected. If you want to modify additional text nodes you need to select them explicitly with `/text()`. ```{r} x <- read_xml("

This is some text. This is more.

") xml_text(x) xml_text(x) <- "This is some other text." xml_text(x) # You can avoid this by explicitly selecting the text node. x <- read_xml("

This is some text. This is bold!

") text_only <- xml_find_all(x, "//text()") xml_text(text_only) <- c("This is some other text. ", "Still bold!") xml_text(x) xml_structure(x) ``` ## Attribute and Namespace Definition Modification ## Attributes and namespace definitions are modified one at a time with `xml_attr()` or all at once with `xml_attrs()`. In both cases using `NULL` as the value will remove the attribute completely. ```{r} x <- read_xml("xml2") xml_attr(x, "href") xml_attr(x, "href") <- "https://github.com/r-lib/xml2" xml_attr(x, "href") xml_attrs(x) <- c(id = "xml2", href = "https://github.com/r-lib/xml2") xml_attrs(x) x xml_attrs(x) <- NULL x # Namespaces are added with as a xmlns or xmlns:prefix attribute xml_attr(x, "xmlns") <- "http://foo" x xml_attr(x, "xmlns:bar") <- "http://bar" x ``` ## Name Modification ## Node names are modified with `xml_name()`. ```{r} x <- read_xml("") x xml_name(x) xml_name(x) <- "c" x ``` # Node modification # All of these functions have a `.copy` argument. If this is set to `FALSE` they will remove the new node from its location before inserting it into the new location. Otherwise they make a copy of the node before insertion. ## Replacing existing nodes ## ```{r} x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] t2 <- children[[2]] t3 <- xml_children(children[[2]])[[1]] xml_replace(t1, t3) x ``` ## Add a sibling ## ```{r} x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] t2 <- children[[2]] t3 <- xml_children(children[[2]])[[1]] xml_add_sibling(t1, t3) x xml_add_sibling(t3, t1, where = "before") x ``` ## Add a child ## ```{r} x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] t2 <- children[[2]] t3 <- xml_children(children[[2]])[[1]] xml_add_child(t1, t3) x xml_add_child(t1, read_xml("")) x ``` ## Removing nodes ## The `xml_remove()` can be used to remove a node (and its children) from a tree. The default behavior is to unlink the node from the tree, but does _not_ free the memory for the node, so R objects pointing to the node are still valid. This allows code like the following to work without crashing R ```{r} x <- read_xml("") x1 <- x %>% xml_children() %>% .[[1]] x2 <- x1 %>% xml_children() %>% .[[1]] xml_remove(x1) rm(x1) gc() x2 ``` If you are not planning on referencing these nodes again this memory is wasted. Calling `xml_remove(free = TRUE)` will remove the nodes _and_ free the memory used to store them. **Note** In this case _any_ node which previously pointed to the node or its children will instead be pointing to free memory and may cause R to crash. xml2 can't figure this out for you, so it's your responsibility to remove any objects which are no longer valid. In particular `xml_find_*()` results are easy to overlook, for example ```{r} x <- read_xml("") bees <- xml_find_all(x, "//b") xml_remove(xml_child(x), free = TRUE) # bees[[1]] is no longer valid!!! rm(bees) gc() ``` ## Namespaces ## We want to construct a document with the following namespace layout. (From ). ```xml My Layer ``` ```{r} d <- xml_new_root("sld", "xmlns" = "http://www.opengis.net/sld", "xmlns:ogc" = "http://www.opengis.net/ogc", "xmlns:se" = "http://www.opengis.net//se", version = "1.1.0" ) %>% xml_add_child("layer") %>% xml_add_child("se:Name", "My Layer") %>% xml_root() d ``` xml2/inst/extdata/0000755000176200001440000000000014727652467013567 5ustar liggesusersxml2/inst/extdata/r-project.html0000644000176200001440000001160114727652467016361 0ustar liggesusers R: The R Project for Statistical Computing

The R Project for Statistical Computing

Getting Started

R is a free software environment for statistical computing and graphics. It compiles and runs on a wide variety of UNIX platforms, Windows and MacOS. To download R, please choose your preferred CRAN mirror.

If you have questions about R like how to download and install the software, or what the license terms are, please read our answers to frequently asked questions before you send an email.

News

  • R 3.2.0 (Full of Ingredients) prerelease versions will appear starting March 19. Final release is scheduled for 2015-04-16.

  • R version 3.1.3 (Smooth Sidewalk) has been released on 2015-03-09.

  • The R Journal Volume 6/2 is available.

  • R version 3.1.2 (Pumpkin Helmet) has been released on 2014-10-31.

  • useR! 2015, will take place at the University of Aalborg, Denmark, June 30 - July 3, 2015.

  • useR! 2014, took place at the University of California, Los Angeles, USA June 30 - July 3, 2014.

xml2/inst/extdata/cd_catalog.xml0000644000176200001440000001173014727652467016373 0ustar liggesusers Empire Burlesque Bob Dylan USA Columbia 10.90 1985 Hide your heart Bonnie Tylor UK CBS Records 9.90 1988 Greatest Hits Dolly Parton USA RCA 9.90 1982 Still got the blues Gary More UK Virgin redords 10.20 1990 Eros Eros Ramazzotti EU BMG 9.90 1997 One night only Bee Gees UK Polydor 10.90 1998 Sylvias Mother Dr.Hook UK CBS 8.10 1973 Maggie May Rod Stewart UK Pickwick 8.50 1990 Romanza Andrea Bocelli EU Polydor 10.80 1996 When a man loves a woman Percy Sledge USA Atlantic 8.70 1987 Black angel Savage Rose EU Mega 10.90 1995 1999 Grammy Nominees Many USA Grammy 10.20 1999 For the good times Kenny Rogers UK Mucik Master 8.70 1995 Big Willie style Will Smith USA Columbia 9.90 1997 Tupelo Honey Van Morrison UK Polydor 8.20 1971 Soulsville Jorn Hoel Norway WEA 7.90 1996 The very best of Cat Stevens UK Island 8.90 1990 Stop Sam Brown UK A and M 8.90 1988 Bridge of Spies T`Pau UK Siren 7.90 1987 Private Dancer Tina Turner UK Capitol 8.90 1983 Midt om natten Kim Larsen EU Medley 7.80 1983 Pavarotti Gala Concert Luciano Pavarotti UK DECCA 9.90 1991 The dock of the bay Otis Redding USA Atlantic 7.90 1987 Picture book Simply Red EU Elektra 7.20 1985 Red The Communards UK London 7.80 1987 Unchain my heart Joe Cocker USA EMI 8.20 1987 xml2/inst/extdata/order-doc.xml0000644000176200001440000000200014727652467016157 0ustar liggesusers Alice Smith 123 Maple Street Mill Valley CA 90952 Robert Smith 8 Oak Avenue Old Town PA 95819 Hurry, my lawn is going wild! Lawnmower 1 148.95 Confirm this is electric Baby Monitor 1 39.98 1999-05-21 xml2/inst/extdata/order-schema.xml0000644000176200001440000000461614727652467016671 0ustar liggesusers Purchase order schema for Example.com. Copyright 2000 Example.com. All rights reserved. Purchase order schema for Example.Microsoft.com. Copyright 2001 Example.Microsoft.com. All rights reserved. Application info. xml2/tools/0000755000176200001440000000000014727652467012320 5ustar liggesusersxml2/tools/winlibs.R0000644000176200001440000000161614760656721014110 0ustar liggesusersif(!file.exists("../windows/libxml2/include/libxml2/libxml")){ unlink("../windows", recursive = TRUE) url <- if(grepl("aarch", R.version$platform)){ "https://github.com/r-windows/bundles/releases/download/libxml2-2.11.5/libxml2-2.11.5-clang-aarch64.tar.xz" } else if(grepl("clang", Sys.getenv('R_COMPILED_BY'))){ "https://github.com/r-windows/bundles/releases/download/libxml2-2.11.5/libxml2-2.11.5-clang-x86_64.tar.xz" } else if(getRversion() >= "4.2") { "https://github.com/r-windows/bundles/releases/download/libxml2-2.11.5/libxml2-2.11.5-ucrt-x86_64.tar.xz" } else { "https://github.com/rwinlib/libxml2/archive/v2.10.3.tar.gz" } download.file(url, basename(url), quiet = TRUE) dir.create("../windows", showWarnings = FALSE) untar(basename(url), exdir = "../windows", tar = 'internal') unlink(basename(url)) setwd("../windows") file.rename(list.files(), 'libxml2') } xml2/README.md0000644000176200001440000000450514727652467012443 0ustar liggesusers # xml2 [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/xml2)](https://cran.r-project.org/package=xml2) [![Codecov test coverage](https://codecov.io/gh/r-lib/xml2/branch/master/graph/badge.svg)](https://app.codecov.io/gh/r-lib/xml2?branch=main) [![R build status](https://github.com/r-lib/xml2/workflows/R-CMD-check/badge.svg)](https://github.com/r-lib/xml2/actions) [![R-CMD-check](https://github.com/r-lib/xml2/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-lib/xml2/actions/workflows/R-CMD-check.yaml) The xml2 package is a binding to [libxml2](http://xmlsoft.org), making it easy to work with HTML and XML from R. The API is somewhat inspired by [jQuery](https://jquery.com). ## Installation You can install xml2 from CRAN, ``` r install.packages("xml2") ``` or you can install the development version from github, using `pak`: ``` r # install.packages("pak") pak::pak("r-lib/xml2") ``` ## Usage ``` r library(xml2) x <- read_xml(" text ") x xml_name(x) xml_children(x) xml_text(x) xml_find_all(x, ".//baz") h <- read_html("

Hi !") h xml_name(h) xml_text(h) ``` There are three key classes: - `xml_node`: a single node in a document. - `xml_doc`: the complete document. Acting on a document is usually the same as acting on the root node of the document. - `xml_nodeset`: a **set** of nodes within the document. Operations on `xml_nodeset`s are vectorised, apply the operation over each node in the set. ## Compared to the XML package xml2 has similar goals to the XML package. The main differences are: - xml2 takes care of memory management for you. It will automatically free the memory used by an XML document as soon as the last reference to it goes away. - xml2 has a very simple class hierarchy so you don’t need to think about exactly what type of object you have, xml2 will just do the right thing. - More convenient handling of namespaces in Xpath expressions - see `xml_ns()` and `xml_ns_strip()` to get started. ## Code of Conduct Please note that the xml2 project is released with a [Contributor Code of Conduct](https://xml2.r-lib.org/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms. xml2/build/0000755000176200001440000000000014765037413012245 5ustar liggesusersxml2/build/vignette.rds0000644000176200001440000000031414765037413014602 0ustar liggesusers‹‹àb```b`a’Ì@&³0`b fd`aà±sóS2Ó2“K2óóô‚rSÐäýòSR|‘¡+@1 £$7Mª @ǃe!ª€€… I5k^bnj1šì.©©y) áØõ3þGÓÂáZYž_Óƒ¢† ª†Å-3'foHf œÃàâe2¡»Ã|÷så—ëÁüÀ Š€ ñÐ=šœ“XŒîQ®”Ä’D½´" ~»$äÍÞæQ5²¿¹‘ð©^ª8Œòp„Ö1$Cv ÐzÐ"€#(r§á¬Óƒ¤´ñvPršÖ¹û±êt¦–·WV]ôéE؈WÈbym×âñÓ b÷ÜÉ32::A‰Ät3ba­-mì®Nµ5]‡{¶¶_m,m}»;úØwn.£a_£üºqFöÔ£Ó¶¯zì”#=¯b­”bv|4µº¼Í\$ûŽéj*µ¢]ºþ‹·³¸ƒòÎ9ïLÛÆàÅ‹ƒk±@½*~«÷U¼¿'0®vÕªçƒñdµ†?A9Póä>\‘.P#¯Š cwØlŒÚbA$þÛMv- ý]ÄPþḠKÐÆ‹Åýäû@C¸©N°^G¡!Ä(ŠVý²žëÙÆn¢|34_ÚÇ}¸…8Œr €«zÜÓ ßº bAØýn©Ëq8ßz!ÙÊL‰fH‚é•tzPÒä€zqݼõŠÓSúÖæj`÷þ°3R›!Rã²}kÆU0Þ–!5»E\ÛßÚÝBnUËa]ÿ6llG¹ýÚ0®ÿuÛ0¾{v-uÖûáq:z !ÞA9På·)ãFͰ§ÍÂæ7e À=Äû(ß?§¦Œá¹PMaGÛ”)L¡¹ò9™šœžñ¯GœõbÇ1Õ2ªNƒ7÷P›{±( ì}Ô0ºF6|(BPµýB7þŸ¢6ŸFj¿¨ÿQÔð\ÿ1L0TãïšlWº¤ ‡n¯½˜Ög±°=ÿ­ï×Ï0Û6¶;s ‡UçAÌ´¯ˆC ¶SŸj=ŒY^ÇF¼Æ>×ê<^"º¡±¶m‚¤MÀ«°Î=sæYCÕ~Kó!ò påéæsìÒÛÆh¨þÂ.5’’¡„JFžB‰#E ^¡,TdoÏÈ[MÖɉ$Ë~31ŽŠ¾@ùEèL|Áôfg5LU”Cå ÛY*éMŸ ?F%¿@ù‹ÀU©f¼ÚÍ…VÄ~îc$#àÊ ‘9ÜÎ4 Ýü-$7ø5Ê_‡¶_7#Ø‘r~ÙZ,".£¼Z›Ë’¢‚,SqÂ/[>G†r¯‹"bKo–ea!€. Ð â'(G7>ïIH®ñÊáGç‡dCÍ2_.ŠUoÅìÑHJkÝEœAy&2k]JþÄL_#>CùYsÌ4‹øåçáÃHÏh»žA^ ¾DùedéHd~žökðùqÄ^”{o®© éHª-â·Š@ú}ˆý(÷GXEN}WÐä:âM”½úðo+ˆ·PŽ §È È#(DXE~–ŠA,BÇPkŽEn#~†òg¡-òÀ k!J†Z ‰54ò))YµPÔ¨®SÑwT|€¸Žòzó{Ütþ{߬ç.m(-™”û‚H:Qs+@ç»d¬¸sªFýæ‡_[ñ Êß„ÎO†B8a. >UJ €Ü„–Èêë„\’}È%{å+Í'$•C¼š­FKÀƽª,ó¥ÝdÌŠ"&c!טZu8´šÙ-Ò¬”;cõK¤9¡$•1VÇ̺i/býxEfÍoù‚æˆ+(¯„6óKzé'’N‰næAb}ùýͲº:4æ–uý%æB˜“fA¿¹Fu ýæb ™øå—¡sñÔ™šKæù²çk&Mm“SsDPD" Ù#–-…ÐÓ¢,e%Ão&¦QqÀ(¿‰¯Ê”% œ÷1¯Î²ÀÚBõD'gj  —ŠE™£š_où%j øÊ_5Þ[NrÉ>EùióÝ$¿À!^ÍVcKÀÆÆxËK‰„_v@/4ŽØƒrO`GéTèó%Q” ,dæWÑÃð V½­wÖz½û9¹Ñ¬žEÛΡ<×|:AòóâÕl5¸h «ãø~ѧróÈfÀ~”E‰®J=Ù.Z¼f®ÙŒb¡9-ÈV?³ö“H9"tšû%÷<Þ¸ˆòbãÉ=&|†r ±p¬‚äŸsˆW³ÕàÚÊF’_QûTî)úiXrÛÊU)µ¸K “ÕØïÐíÀV–2°€Åz-A¾§š ï® ¬sIT߯žâ}€ß¢ümœ˜Ûk¬…µúZpå½Ðäk'äÜô¨Ë>\ar^ʹ*5À¢aõ˜j PMS5¿•#2õü¹ÏÆP§ÅຠîÜÚ.o±qAø;¤—2º!%ƒï²ø—¶Üb°§^Ù[ÙØ^Z¹P–UA4›{zjP úoÀjj´ˆÜ"r"/íí]¬`â¦=@Ë”#‚ahR†ùå–?nÑØ‹ÆÝŒ)ß-m¬_,‡|ãX%Q`!ʼndäMÏÌôlѸEcÂÄqÇ€ Åâ›ð2Þï[;¢Ñ¢ª-oÜ¢±{¶¶ß-¥¶Ö·^_("—‰|"h “µ¨Ü¢ò‹Õ•¥­½õå‹Åä"ŲU.ÙÿŒ‹“CL¶Ó](&j´ S’‘åˆ(ªØêæµ8ìÉáŽÝ¥ý© ÅßOK:5;v ÌߤZNÈRK2ß4·èÜ¢³yº÷×·–7ÞÚsÇ/¥ï¯ÃesjÞþº’•K"%å·#þ÷Ïhú·Cèέí­Õ½ Åækª–‘D¢PãDÕŽˆÍR½c´8ìÅá®­í•õå‹Eâ±ë\ÚáFVeÆ©ADÉ\A"h­8£Ei/JÇ·v—7V—¶.§Ç±ç§Q±¤Àh1*²èY'"ÍÊ‚&™e×"öo‰ØÛË+K{KŠØ#ªRb*“ŠM?ÝÙh1¹“{·¶¡3¸µ}Á:ƒãx¢Ý!žwGì.+ÙÝ[Jí%W·VZÜnq»¾—^ÞÞÜYº`!õ?À:l!k½ È2礿f@ ª(夬utœj-X44J­e~T$BΠډ ‰:7×ÅU]—2òÉj‚ž‡•$æR@íÌ\/;+?åq«²´*‹/;·7V¦&/TU³ÖJY»„íon<™JLâÆ¤T4ç7ͶÝb´}z¶¶_-í®®­ï_,Vcd““NKÅJXsZ`ï9RÒ¤VPÓbµ«;Þ¼}}±BõÇ•…S"(pî´&Âæ@"‘¥‚Ä8®©3ú°ÖÿµhÝ¢µ‰ºXø±»t±<õ#>þ`ÊMsïÙ1 ™NÌ'&[´nÑÚƒB½ë¯·¶S««[k"ßCéPþÚÓE*»â”7šÉ³ïZÌn1ÛƒA=¯Ö_l¬o­^¬y}ŸïÀëŒtÈB…êD)2TÓa_*s¬eg÷»u{SYl‘ûÂä¾'-R=«I·m%#Iî¨|“açÇý}‹•Ÿ{<³=%º<ï²x¦)»& ‡±Ê6ƒ]Aìý”Ëí[”ßÉmÿ¯µª„çÀwâÕl*~y²¯ˆý[·}€ŠOí` ž8â•XØÍ/9´š{—§ õÖæöнªÞé“Û³rD€ßÝ×P^ mè×°»Qò´ »ï\WÞ%GAd—Ý_±¯üfæR0ºC‚çKpàlXÒ­½’¦è Ãæ|ÄüÚÚV5£«2lï%|*ÿäv\jt£³È%jÀp5’Ê!^ÍVã–€q8mŠOµ^Æ,ïbc¸Ã[:ê\ZÏ‘ õ"ö¡ü›š/«Év'²×NØ/1w€7Q¾aýñØ ’ëG¼…rø½É§aËÒÚ­ÞfÎ ñ2Ÿcnê\¤¾w`}‡×Q^­÷³…dÅÚaÁÔrnæ(ã×!.YÌ01ÔéÒþâK.Ù»(ßm¾'‚äïqˆW³Õx…%`ccbúó©;Gì…ÝʱÝ5ƒúÅ`: dÕ’ÕÔ¢&Á¦ºZð³,ã}€«(¯†÷jÉ(– s«4V¶g¤\/™’fv¤°ŒHLi˜²Î2è·v® §Qžn|í\æ’åv0nvµ€äg8Ä+¢Ü÷¦Ë›âº¤ý³½¦J6¦Û¸jU£2âÐ[8ãßê@‡¦›C¼B’åå’Rµ5z‚¼Ùcš{ŒkA–°—`îÌbÞùÄòá ^ûÍד)7N/Cçb Ž›;²†lMÒ…Ì=¹0] +à–ŒuSFcÝ8ªM ó-°­ß¼¼Aýß UÚbQt7ïà¦uU2°Én±¨©§’•ßÇ…¬£V€ÑG]iÆŠ’[i—Æ7ajuøü ÖZÃÕ`g“ê[Øùõ ‡x…,•ÁÍf­U5¨¡¾Y²Dy02–ôái±²²¦T ÅÍóåÊ&òÃÆÐ\q_+ºK ØwÂt@£%ÎÇΊ›´gê&§Sdü h±Yƒ}rr’84¿JdÕB’}Ÿ€÷º}VSˆuâˆÜ±R®¦\ˆá‘Lí¾»Šþ<âW(ŸÃ Ö},£ ­ŸýŽUÕ¬ ”CÐ7{{;<éáÅþÛÔÆxÓ/ÚÁ„Žm}fáw¨6 ÷ª?D-pÝ.ޱ_[X`:`pN:÷$|=@”Q–#$¼,)GÖ—å{RâŠÃU¹¹j榒™Yùqåý Y©yò båB„…äñº’{ލ ¬„®f1@Ùªˆ:Êz£è\*w³ÑùŸÿåi¯üêÊÞÒ»ˆu4ÿ'Ä?¢üÇÈØû3â¿¢ü¯Ía¯ø'”ÿ¾Mó@úÿ†øg”ÿÜü6í{‹ïe ÷rÚYsöj‚šª4Z /é©›ÙAˆô5ù¢<ØQù4 ®9>öª{ž³Z íˆ#~ò÷'ÚXš?TËÍ60$æ¯f«‘ư1<Ïxü³æ‰&QN6ÓSŽ3@ã~ÄOPþ$Oý#VÀÉXùôïFW ‘&€S(O…fî’Í Ê¡9Äeޱ’.ἎCYÍÀf°¾‡@ÅiÄïPÖm®Çî!‹ÝpJIPzÿÄ®ûˆS(*Sÿô¾fjÏ)@õ~Ä;(~«\óä8â4ÊÓç÷OÈiÀèæáL›}ÉLe¦µEwÓ Z(ªš Iò™ïÞ8è;ƒHQ¦‘WwZ·æ…¹¤¼…¥t ÛˆðßúnË ùvñj¶%`c¸&õòǪãg ÖSʈWÈb™#Öº Øô! 1 ¼‘`ìΕ¬EÖÖ@-zN§ñT;ƒE8‰òdhµïäǦñøèbNUŸ/f$Ÿ/&áÑǾµÌ¢f€÷Q¾ZË/L-¡L™šÏ Ééó7 ‹f‰ÑXD-¿@9ükù»ÞБ¢^€M˜¨ì©GÓ¶1Çv}Œ¬YSne5ËêOQ0ò¾U;Du¯£|=´jk3êg:k°^a|”ž¢`£dT{RÔÔß³¶Àê÷M0õ³G¬ÏHž‘Q8%›õ}g&\C9ü^ÿö–0mùîŸäéñzá÷1kx…,–þ2ýJš÷¢:•ްTíùµæ¥W¿¦ÉŠdñ )ûfàѶã£Yñ ËÈ'«‡‰Ss¤Á¯Ò2* ˜D9ZéÏ ´¬´åøðåR^Y5¡üìíù¼4- v€Ÿ¡üY„1œ¨*†Vr‹á~©)¡©® Búíâ\“íIÛñˆG ÙV›S^ñ£Š¹¶1T ¸¯ý®IÓþWÄlÇ‚dîpN¼‡Ï*w„¬¦Â LÉÿ«Ì[ÊVžZ)³´!d*)´]q¹§Çd¹Auƒ»±Û©JZ%Açîèr}”½‘wc‡ã&¨UÙ½³"­¾‡·BùÞxÚììñ·^wÜr)ÕªsèÌ]y“òMŽ›:ÓŠj¸èã¸I¤Pª5qUúrÚ<{åÛ‡*·»üD¡'YµP‘ûÉ­:?‰§í·|åÛû\µ¶f‰•oºQýLïçI9E¬úéhMÙkTŽâ™S÷¹iÜ…ÁþÁe×›2ª,ÖÞäR RŽÊ:ÿ¼›5ZîΨ‘Wùç y>O74µŠ¿ÞI»=µê–^VJs+cî®k.ëNgU%K‹|tVÞ—oꬩ¨¸¬ |ÇÕŸÀ*i¥;ÒÅ#—üW§2FQâ¹1Vó”cAûÀSì!%'w%£S*ȺúêÙŸÖ¨W%rØM(1»i1ï’îJ—t¢W³+ ºÒ²¨¼AÜ\,7T¾/îñDÇŒOYáI†K=riÌý,x/áâÿ™5ysºY‚9Àš¬:kÚ—^5ÍQ¬Y*ÉUñª‘U+àxR»dT-ÕõôBÌ"0gT«ó\SQŽ?Xpz^=ù@ÁÅÓ)q»X¥oÝ:ÒbŽ·üe—ÃROÝúÓE˜L ³é *Ö¹³Æ¸ÕÕxZü»’úQ„ëJ›CµõÕÅ à(g…$ÞÅÚ¢š¦¨ŽmaŨô³‹Ïu¹÷ˆž¨šøÚ¶§SuÈߙ֙sv§Ÿ3Ø ¼nn‘k‡ê·[œdÚº6ޤ­µ´å›Ý“6'e~D‰t¦…LÆÅË{ÜlMÏ«®ô²ªÂnÓ«}Ÿ[ u¥iAd÷Äõ…ìV½6GÏ ¯}vg²² ë1ïúg¿*ßÐïò°ž´~¦¨E]rÄÌŽ<ìÒÓ"_€=.º”®jiíu'+ˆbþ#Ê¡#}”©ç .³4GY+š¥**æ½Báº.”rUo(#c+|û×n'1âÑ-¬«ÉÄ|†¤HØò?Z± þê°/Å3MœÐ –ô³LI’Åߪ*ë )ñ•:àZåñѱ©ÑÇ¿¸ô ïYÊšÈ †ÚýB¾ßŸuÖtóßî­=Á)¡]Î/cÖçÝ DmKÿõ߯æ_ÚŸ—;›ívEÞÙÞ]ßÏ6ÙÌ?JÉ÷:XNnHMÐÎ’ksQ°€žL%röÉÎ×Ö“z^Ðh2%&­.jG?íÎòeç£H5é˜ÅÁI&s,¸g•<93—<1ÎŽ¿Ì=Uæ§æfçO£¨LfåÙ™IöïPIî%SF¡˜z*ÒÔi2eZgž~97;3Kç§æg`c©éj>Õô¹ã¬Ï]¯[jÕÖÁT 2Rç-Ÿ×P¯ŠnðÝÁNj|lÊ•`7T€ö~M‹‚å>z°Ã£åÞöè>—Ñáà}€]³÷°Žáô—÷½o¥ðË/¿¼·—jXóª]>ëŠ(™n%ôÒ IVúÞeô9– àO(ÿY3X‰¶Ww—Së;{ëÛ[Ñ”E€ØšÓÁ»<aºÄÖà»–pP0Š"xῬ1IïÜŠ9ä&!Gà;Ò¢*E“ï'۲ļsùsøå—¡m™ ùYñj¶·°ll §/±ØÅ§bÃHcÀ”{¢£´ ŠæÄyA&åõW¤(踓åù>Ù”íCœFyºñ”æ§Ý¹lQÕ,. c²qæ|j×ok ¥ã‰ûTî6R°?Vs£Oåœ[ŠôˆÖI¤ $€ZׇQ6.æVV]öê-ß:}Šøå‡öäìh® >BùQh&È÷TS¡ý4ãA5ç—Ø Ï8âS”ŸÑËœì3¶žñ“\¹3BBS;ñËÝèô¨W߃q82Ý\uê_3u"֨祚¿¶ª1¬i‘·.y¯(êH³²`í+y¡H<¼¢©Es—Wó¨ÑóײÅç Ïç~ÆgZ(g†pè7k,R´ SbªGÎS½/<»O¼~i,…¯¯Hºy¾ð>L̘"Z©¼AZ‹Å-×zc<+ôRy€EÈY$r‹Ç-×ïâ z€¹2%ð5$0L”kõòZü­;$Éø{Q=°u}‹Á-×cð€5Èvp’gVÁ] .—âxœŽBUyÇ-ÃÁÌ‚Â>`½"˜5jàoaŠßÜŒaÆBçÆµÏiMä‚Åָߍ—£ñZ;ñ™E@o¡|+Bÿæq0%¿Rtk;`‚’O#ˆwP¾™« dž2ÄBcˆ3(š™èßBwgQ?Ç÷*«fUÒ1 p.((3‡¸‚r fÑ5UÇñ®~ˆú ¶ÆëÛÝCòí†k}Â/›~³ÖÛè8”3`±ÜÍ;N$[,>#}º˜,9)’ß ÐŽ­î6ÎtžzŒcÚ6FC¡Q£P„Ò‚#wÍCáôÔ·c3ç[ÑǨ ×"‡Tôae-|~‚0­ÝúW–ߎó!ÊÃû* ߆¤P}œiê_+îDR~MlÓ9Ç­¹Šs÷ÆpñLù$þ=‰o%¹Znºóˆ[\%á¨! çZΙpIÔ$–p®ÉÖ=oЮu“‘rÌwÓÉ·s¸it½«þyƒS˜íX¬»õSᳫðY‡õÐ_c•AÒ»]›}^5o Îa£Èè}]Çv ð]y×L{çËËüî¢îU?2ö·ÿ3g¦Ýû5xml2/configure0000755000176200001440000000555214765037414013065 0ustar liggesusers#!/bin/sh # Anticonf (tm) script by Jeroen Ooms (2015) # This script will query 'pkg-config' for the required cflags and ldflags. # If pkg-config is unavailable or does not find the library, try setting # INCLUDE_DIR and LIB_DIR manually via e.g: # R CMD INSTALL --configure-vars='INCLUDE_DIR=/.../include LIB_DIR=/.../lib' # Library settings PKG_CONFIG_NAME="libxml-2.0" PKG_DEB_NAME="libxml2-dev" PKG_RPM_NAME="libxml2-devel" PKG_CSW_NAME="libxml2_dev" PKG_TEST_HEADER="" PKG_LIBS="-lxml2" # Note that cflags may be empty in case of success if [ "$INCLUDE_DIR" ] || [ "$LIB_DIR" ]; then echo "Found INCLUDE_DIR and/or LIB_DIR!" PKG_CFLAGS="-I$INCLUDE_DIR $PKG_CFLAGS" PKG_LIBS="-L$LIB_DIR $PKG_LIBS" else # Use xml2-config if available xml2-config --version >/dev/null 2>&1 if [ $? -eq 0 ]; then PKGCONFIG_CFLAGS=`xml2-config --cflags` PKGCONFIG_LIBS=`xml2-config --libs` # Fix a missing libxml2 directory on the requested include directory # https://github.com/r-lib/xml2/issues/296 if [ `uname` = "Darwin" ] && echo "${PKGCONFIG_CFLAGS}" | grep -sq "/usr/include$"; then PKGCONFIG_CFLAGS="$PKGCONFIG_CFLAGS/libxml2" fi else pkg-config --version >/dev/null 2>&1 if [ $? -eq 0 ]; then PKGCONFIG_CFLAGS=`pkg-config --cflags $PKG_CONFIG_NAME` PKGCONFIG_LIBS=`pkg-config --libs $PKG_CONFIG_NAME` fi fi if [ "$PKGCONFIG_CFLAGS" ] || [ "$PKGCONFIG_LIBS" ]; then echo "Found pkg-config cflags and libs!" PKG_CFLAGS=${PKGCONFIG_CFLAGS} PKG_LIBS=${PKGCONFIG_LIBS} fi fi # Find compiler CC=`${R_HOME}/bin/R CMD config CC` CFLAGS=`${R_HOME}/bin/R CMD config CFLAGS` CPPFLAGS=`${R_HOME}/bin/R CMD config CPPFLAGS` # For debugging echo "Using PKG_CFLAGS=$PKG_CFLAGS" echo "Using PKG_LIBS=$PKG_LIBS" # Test configuration echo "#include $PKG_TEST_HEADER" | ${CC} ${CPPFLAGS} ${PKG_CFLAGS} ${CFLAGS} -E -xc - >/dev/null 2>configure.log # Customize the error if [ $? -ne 0 ]; then echo "------------------------- ANTICONF ERROR ---------------------------" echo "Configuration failed because $PKG_CONFIG_NAME was not found. Try installing:" echo " * deb: $PKG_DEB_NAME (Debian, Ubuntu, etc)" echo " * rpm: $PKG_RPM_NAME (Fedora, CentOS, RHEL)" echo " * csw: $PKG_CSW_NAME (Solaris)" echo "If $PKG_CONFIG_NAME is already installed, check that 'pkg-config' is in your" echo "PATH and PKG_CONFIG_PATH contains a $PKG_CONFIG_NAME.pc file. If pkg-config" echo "is unavailable you can set INCLUDE_DIR and LIB_DIR manually via:" echo "R CMD INSTALL --configure-vars='INCLUDE_DIR=... LIB_DIR=...'" echo "-------------------------- [ERROR MESSAGE] ---------------------------" cat configure.log echo "--------------------------------------------------------------------" exit 1 fi # Write to Makevars sed -e "s|@cflags@|$PKG_CFLAGS|" -e "s|@libs@|$PKG_LIBS|" src/Makevars.in > src/Makevars # Success exit 0 xml2/man/0000755000176200001440000000000014727652467011733 5ustar liggesusersxml2/man/xml_replace.Rd0000644000176200001440000000336114727652467014520 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_modify.R \name{xml_replace} \alias{xml_replace} \alias{xml_add_sibling} \alias{xml_add_child} \alias{xml_add_parent} \alias{xml_remove} \title{Modify a tree by inserting, replacing or removing nodes} \usage{ xml_replace(.x, .value, ..., .copy = TRUE) xml_add_sibling(.x, .value, ..., .where = c("after", "before"), .copy = TRUE) xml_add_child(.x, .value, ..., .where = length(xml_children(.x)), .copy = TRUE) xml_add_parent(.x, .value, ...) xml_remove(.x, free = FALSE) } \arguments{ \item{.x}{a document, node or nodeset.} \item{.value}{node to insert.} \item{...}{If named attributes or namespaces to set on the node, if unnamed text to assign to the node.} \item{.copy}{whether to copy the \code{.value} before replacing. If this is \code{FALSE} then the node will be moved from it's current location.} \item{.where}{to add the new node, for \code{xml_add_child} the position after which to add, use \code{0} for the first child. For \code{xml_add_sibling} either \sQuote{"before"} or \sQuote{"after"} indicating if the new node should be before or after \code{.x}.} \item{free}{When removing the node also free the memory used for that node. Note if you use this option you cannot use any existing objects pointing to the node or its children, it is likely to crash R or return garbage.} } \description{ \code{xml_add_sibling()} and \code{xml_add_child()} are used to insert a node as a sibling or a child. \code{xml_add_parent()} adds a new parent in between the input node and the current parent. \code{xml_replace()} replaces an existing node with a new node. \code{xml_remove()} removes a node from the tree. } \details{ Care needs to be taken when using \code{xml_remove()}, } xml2/man/xml2-package.Rd0000644000176200001440000000145414727652467014501 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml2-package.R \docType{package} \name{xml2-package} \alias{xml2} \alias{xml2-package} \title{xml2: Parse XML} \description{ Work with XML files using a simple, consistent interface. Built on top of the 'libxml2' C library. } \seealso{ Useful links: \itemize{ \item \url{https://xml2.r-lib.org} \item \url{https://github.com/r-lib/xml2} \item Report bugs at \url{https://github.com/r-lib/xml2/issues} } } \author{ \strong{Maintainer}: Hadley Wickham \email{hadley@posit.co} Authors: \itemize{ \item Jim Hester \item Jeroen Ooms } Other contributors: \itemize{ \item Posit Software, PBC [copyright holder, funder] \item R Foundation (Copy of R-project homepage cached as example) [contributor] } } \keyword{internal} xml2/man/xml_type.Rd0000644000176200001440000000060514727652467014064 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_type.R \name{xml_type} \alias{xml_type} \title{Determine the type of a node.} \usage{ xml_type(x) } \arguments{ \item{x}{A document, node, or node set.} } \description{ Determine the type of a node. } \examples{ x <- read_xml(" a ") xml_type(x) xml_type(xml_contents(x)) } xml2/man/read_xml.Rd0000644000176200001440000000744214727652467014024 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_parse.R \name{read_xml} \alias{read_xml} \alias{read_html} \alias{read_xml.character} \alias{read_xml.raw} \alias{read_xml.connection} \title{Read HTML or XML.} \usage{ read_xml(x, encoding = "", ..., as_html = FALSE, options = "NOBLANKS") read_html(x, encoding = "", ..., options = c("RECOVER", "NOERROR", "NOBLANKS")) \method{read_xml}{character}(x, encoding = "", ..., as_html = FALSE, options = "NOBLANKS") \method{read_xml}{raw}( x, encoding = "", base_url = "", ..., as_html = FALSE, options = "NOBLANKS" ) \method{read_xml}{connection}( x, encoding = "", n = 64 * 1024, verbose = FALSE, ..., base_url = "", as_html = FALSE, options = "NOBLANKS" ) } \arguments{ \item{x}{A string, a connection, or a raw vector. A string can be either a path, a url or literal xml. Urls will be converted into connections either using \code{base::url} or, if installed, \code{curl::curl}. Local paths ending in \code{.gz}, \code{.bz2}, \code{.xz}, \code{.zip} will be automatically uncompressed. If a connection, the complete connection is read into a raw vector before being parsed.} \item{encoding}{Specify a default encoding for the document. Unless otherwise specified XML documents are assumed to be in UTF-8 or UTF-16. If the document is not UTF-8/16, and lacks an explicit encoding directive, this allows you to supply a default.} \item{...}{Additional arguments passed on to methods.} \item{as_html}{Optionally parse an xml file as if it's html.} \item{options}{Set parsing options for the libxml2 parser. Zero or more of \Sexpr[results=rd, stage=build]{xml2:::describe_options(xml2:::xml_parse_options())}} \item{base_url}{When loading from a connection, raw vector or literal html/xml, this allows you to specify a base url for the document. Base urls are used to turn relative urls into absolute urls.} \item{n}{If \code{file} is a connection, the number of bytes to read per iteration. Defaults to 64kb.} \item{verbose}{When reading from a slow connection, this prints some output on every iteration so you know its working.} } \value{ An XML document. HTML is normalised to valid XML - this may not be exactly the same transformation performed by the browser, but it's a reasonable approximation. } \description{ Read HTML or XML. } \section{Setting the "user agent" header}{ When performing web scraping tasks it is both good practice --- and often required --- to set the \href{https://en.wikipedia.org/wiki/User_agent}{user agent} request header to a specific value. Sometimes this value is assigned to emulate a browser in order to have content render in a certain way (e.g. \verb{Mozilla/5.0 (Windows NT 5.1; rv:52.0) Gecko/20100101 Firefox/52.0} to emulate more recent Windows browsers). Most often, this value should be set to provide the web resource owner information on who you are and the intent of your actions like this Google scraping bot user agent identifier: \verb{Googlebot/2.1 (+http://www.google.com/bot.html)}. You can set the HTTP user agent for URL-based requests using \code{\link[httr:set_config]{httr::set_config()}} and \code{\link[httr:user_agent]{httr::user_agent()}}: \code{httr::set_config(httr::user_agent("me@example.com; +https://example.com/info.html"))} \code{\link[httr:set_config]{httr::set_config()}} changes the configuration globally, \code{\link[httr:with_config]{httr::with_config()}} can be used to change configuration temporarily. } \examples{ # Literal xml/html is useful for small examples read_xml("") read_html("Hi<title></html>") read_html("<html><title>Hi") # From a local path read_html(system.file("extdata", "r-project.html", package = "xml2")) \dontrun{ # From a url cd <- read_xml(xml2_example("cd_catalog.xml")) me <- read_html("http://had.co.nz") } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_find_all.Rd����������������������������������������������������������������������������0000644�0001762�0000144�00000010430�14727652467�014650� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_find.R \name{xml_find_all} \alias{xml_find_all} \alias{xml_find_all.xml_nodeset} \alias{xml_find_first} \alias{xml_find_num} \alias{xml_find_int} \alias{xml_find_chr} \alias{xml_find_lgl} \alias{xml_find_one} \title{Find nodes that match an xpath expression.} \usage{ xml_find_all(x, xpath, ns = xml_ns(x), ...) \method{xml_find_all}{xml_nodeset}(x, xpath, ns = xml_ns(x), flatten = TRUE, ...) xml_find_first(x, xpath, ns = xml_ns(x)) xml_find_num(x, xpath, ns = xml_ns(x)) xml_find_int(x, xpath, ns = xml_ns(x)) xml_find_chr(x, xpath, ns = xml_ns(x)) xml_find_lgl(x, xpath, ns = xml_ns(x)) } \arguments{ \item{x}{A document, node, or node set.} \item{xpath}{A string containing an xpath (1.0) expression.} \item{ns}{Optionally, a named vector giving prefix-url pairs, as produced by \code{\link[=xml_ns]{xml_ns()}}. If provided, all names will be explicitly qualified with the ns prefix, i.e. if the element \code{bar} is defined in namespace \code{foo}, it will be called \code{foo:bar}. (And similarly for attributes). Default namespaces must be given an explicit name. The ns is ignored when using \code{\link[=xml_name<-]{xml_name<-()}} and \code{\link[=xml_set_name]{xml_set_name()}}.} \item{...}{Further arguments passed to or from other methods.} \item{flatten}{A logical indicating whether to return a single, flattened nodeset or a list of nodesets.} } \value{ \code{xml_find_all} returns a nodeset if applied to a node, and a nodeset or a list of nodesets if applied to a nodeset. If there are no matches, the nodeset(s) will be empty. Within each nodeset, the result will always be unique; repeated nodes are automatically de-duplicated. \code{xml_find_first} returns a node if applied to a node, and a nodeset if applied to a nodeset. The output is \emph{always} the same size as the input. If there are no matches, \code{xml_find_first} will return a missing node; if there are multiple matches, it will return the first only. \code{xml_find_num}, \code{xml_find_chr}, \code{xml_find_lgl} return numeric, character and logical results respectively. } \description{ Xpath is like regular expressions for trees - it's worth learning if you're trying to extract nodes from arbitrary locations in a document. Use \code{xml_find_all} to find all matches - if there's no match you'll get an empty result. Use \code{xml_find_first} to find a specific match - if there's no match you'll get an \code{xml_missing} node. } \section{Deprecated functions}{ \code{xml_find_one()} has been deprecated. Instead use \code{xml_find_first()}. } \examples{ x <- read_xml("<foo><bar><baz/></bar><baz/></foo>") xml_find_all(x, ".//baz") xml_path(xml_find_all(x, ".//baz")) # Note the difference between .// and // # // finds anywhere in the document (ignoring the current node) # .// finds anywhere beneath the current node (bar <- xml_find_all(x, ".//bar")) xml_find_all(bar, ".//baz") xml_find_all(bar, "//baz") # Find all vs find one ----------------------------------------------------- x <- read_xml("<body> <p>Some <b>text</b>.</p> <p>Some <b>other</b> <b>text</b>.</p> <p>No bold here!</p> </body>") para <- xml_find_all(x, ".//p") # By default, if you apply xml_find_all to a nodeset, it finds all matches, # de-duplicates them, and returns as a single nodeset. This means you # never know how many results you'll get xml_find_all(para, ".//b") # If you set flatten to FALSE, though, xml_find_all will return a list of # nodesets, where each nodeset contains the matches for the corresponding # node in the original nodeset. xml_find_all(para, ".//b", flatten = FALSE) # xml_find_first only returns the first match per input node. If there are 0 # matches it will return a missing node xml_find_first(para, ".//b") xml_text(xml_find_first(para, ".//b")) # Namespaces --------------------------------------------------------------- # If the document uses namespaces, you'll need use xml_ns to form # a unique mapping between full namespace url and a short prefix x <- read_xml(' <root xmlns:f = "http://foo.com" xmlns:g = "http://bar.com"> <f:doc><g:baz /></f:doc> <f:doc><g:baz /></f:doc> </root> ') xml_find_all(x, ".//f:doc") xml_find_all(x, ".//f:doc", xml_ns(x)) } \seealso{ \code{\link[=xml_ns_strip]{xml_ns_strip()}} to remove the default namespaces } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_comment.Rd�����������������������������������������������������������������������������0000644�0001762�0000144�00000000625�14727652467�014547� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/classes.R \name{xml_comment} \alias{xml_comment} \title{Construct a comment node} \usage{ xml_comment(content) } \arguments{ \item{content}{The comment content} } \description{ Construct a comment node } \examples{ x <- xml_new_document() r <- xml_add_child(x, "root") xml_add_child(r, xml_comment("Hello!")) as.character(x) } �����������������������������������������������������������������������������������������������������������xml2/man/xml_serialize.Rd���������������������������������������������������������������������������0000644�0001762�0000144�00000001726�14727652467�015077� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_serialize.R \name{xml_serialize} \alias{xml_serialize} \alias{xml_unserialize} \title{Serializing XML objects to connections.} \usage{ xml_serialize(object, connection, ...) xml_unserialize(connection, ...) } \arguments{ \item{object}{\R object to serialize.} \item{connection}{an open \link[base]{connection} or (for \code{serialize}) \code{NULL} or (for \code{unserialize}) a raw vector (see \sQuote{Details}).} \item{...}{Additional arguments passed to \code{\link[=read_xml]{read_xml()}}.} } \value{ For \code{serialize}, \code{NULL} unless \code{connection = NULL}, when the result is returned in a raw vector. For \code{unserialize} an \R object. } \description{ Serializing XML objects to connections. } \examples{ library(xml2) x <- read_xml("<a> <b><c>123</c></b> <b><c>456</c></b> </a>") b <- xml_find_all(x, "//b") out <- xml_serialize(b, NULL) xml_unserialize(out) } ������������������������������������������xml2/man/xml_name.Rd��������������������������������������������������������������������������������0000644�0001762�0000144�00000002255�14727652467�014026� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_name.R \name{xml_name} \alias{xml_name} \alias{xml_name<-} \alias{xml_set_name} \title{The (tag) name of an xml element.} \usage{ xml_name(x, ns = character()) xml_name(x, ns = character()) <- value xml_set_name(x, value, ns = character()) } \arguments{ \item{x}{A document, node, or node set.} \item{ns}{Optionally, a named vector giving prefix-url pairs, as produced by \code{\link[=xml_ns]{xml_ns()}}. If provided, all names will be explicitly qualified with the ns prefix, i.e. if the element \code{bar} is defined in namespace \code{foo}, it will be called \code{foo:bar}. (And similarly for attributes). Default namespaces must be given an explicit name. The ns is ignored when using \code{\link[=xml_name<-]{xml_name<-()}} and \code{\link[=xml_set_name]{xml_set_name()}}.} \item{value}{a character vector with replacement name.} } \value{ A character vector. } \description{ The (tag) name of an xml element. Modify the (tag) name of an element } \examples{ x <- read_xml("<bar>123</bar>") xml_name(x) y <- read_xml("<bar><baz>1</baz>abc<foo /></bar>") z <- xml_children(y) xml_name(xml_children(y)) } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_ns_strip.Rd����������������������������������������������������������������������������0000644�0001762�0000144�00000001302�14727652467�014737� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_modify.R \name{xml_ns_strip} \alias{xml_ns_strip} \title{Strip the default namespaces from a document} \usage{ xml_ns_strip(x) } \arguments{ \item{x}{A document, node, or node set.} } \description{ Strip the default namespaces from a document } \examples{ x <- read_xml( "<foo xmlns = 'http://foo.com'> <baz/> <bar xmlns = 'http://bar.com'> <baz/> </bar> </foo>" ) # Need to specify the default namespaces to find the baz nodes xml_find_all(x, "//d1:baz") xml_find_all(x, "//d2:baz") # After stripping the default namespaces you can find both baz nodes directly xml_ns_strip(x) xml_find_all(x, "//baz") } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_ns.Rd����������������������������������������������������������������������������������0000644�0001762�0000144�00000002621�14727652467�013523� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_namespaces.R \name{xml_ns} \alias{xml_ns} \alias{xml_ns_rename} \title{XML namespaces.} \usage{ xml_ns(x) xml_ns_rename(old, ...) } \arguments{ \item{x}{A document, node, or node set.} \item{old, ...}{An existing xml_namespace object followed by name-value (old prefix-new prefix) pairs to replace.} } \value{ A character vector with class \code{xml_namespace} so the default display is a little nicer. } \description{ \code{xml_ns} extracts all namespaces from a document, matching each unique namespace url with the prefix it was first associated with. Default namespaces are named \code{d1}, \code{d2} etc. Use \code{xml_ns_rename} to change the prefixes. Once you have a namespace object, you can pass it to other functions to work with fully qualified names instead of local names. } \examples{ x <- read_xml(' <root> <doc1 xmlns = "http://foo.com"><baz /></doc1> <doc2 xmlns = "http://bar.com"><baz /></doc2> </root> ') xml_ns(x) # When there are default namespaces, it's a good idea to rename # them to give informative names: ns <- xml_ns_rename(xml_ns(x), d1 = "foo", d2 = "bar") ns # Now we can pass ns to other xml function to use fully qualified names baz <- xml_children(xml_children(x)) xml_name(baz) xml_name(baz, ns) xml_find_all(x, "//baz") xml_find_all(x, "//foo:baz", ns) str(as_list(x)) str(as_list(x, ns)) } ���������������������������������������������������������������������������������������������������������������xml2/man/xml_dtd.Rd���������������������������������������������������������������������������������0000644�0001762�0000144�00000001675�14727652467�013666� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/classes.R \name{xml_dtd} \alias{xml_dtd} \title{Construct a document type definition} \usage{ xml_dtd(name = "", external_id = "", system_id = "") } \arguments{ \item{name}{The name of the declaration} \item{external_id}{The external ID of the declaration} \item{system_id}{The system ID of the declaration} } \description{ This is used to create simple document type definitions. If you need to create a more complicated definition with internal subsets it is recommended to parse a string directly with \code{read_xml()}. } \examples{ r <- xml_new_root( xml_dtd( "html", "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" ) ) # Use read_xml directly for more complicated DTD d <- read_xml( '<!DOCTYPE doc [ <!ELEMENT doc (#PCDATA)> <!ENTITY foo " test "> ]> <doc>This is a valid document &foo; !</doc>' ) } �������������������������������������������������������������������xml2/man/download_xml.Rd����������������������������������������������������������������������������0000644�0001762�0000144�00000003573�14727652467�014721� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_parse.R \name{download_xml} \alias{download_xml} \alias{download_html} \title{Download a HTML or XML file} \usage{ download_xml( url, file = basename(url), quiet = TRUE, mode = "wb", handle = curl::new_handle() ) download_html( url, file = basename(url), quiet = TRUE, mode = "wb", handle = curl::new_handle() ) } \arguments{ \item{url}{A character string naming the URL of a resource to be downloaded.} \item{file}{A character string with the name where the downloaded file is saved.} \item{quiet}{If \code{TRUE}, suppress status messages (if any), and the progress bar.} \item{mode}{A character string specifying the mode with which to write the file. Useful values are \code{"w"}, \code{"wb"} (binary), \code{"a"} (append) and \code{"ab"}.} \item{handle}{a curl handle object} } \value{ Path of downloaded file (invisibly). } \description{ Libcurl implementation of \code{C_download} (the "internal" download method) with added support for https, ftps, gzip, etc. Default behavior is identical to \code{\link[=download.file]{download.file()}}, but request can be fully configured by passing a custom \code{\link[curl:handle]{curl::handle()}}. } \details{ The main difference between \code{curl_download} and \code{curl_fetch_disk} is that \code{curl_download} checks the http status code before starting the download, and raises an error when status is non-successful. The behavior of \code{curl_fetch_disk} on the other hand is to proceed as normal and write the error page to disk in case of a non success response. For a more advanced download interface which supports concurrent requests and resuming large files, have a look at the \link[curl]{multi_download} function. } \examples{ \dontrun{ download_html("http://tidyverse.org/index.html") } } \seealso{ \link[curl:curl_download]{curl_download} } �������������������������������������������������������������������������������������������������������������������������������������xml2/man/url_parse.Rd�������������������������������������������������������������������������������0000644�0001762�0000144�00000001130�14727652467�014211� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_url.R \name{url_parse} \alias{url_parse} \title{Parse a url into its component pieces.} \usage{ url_parse(x) } \arguments{ \item{x}{A character vector of urls.} } \value{ A dataframe with one row for each element of \code{x} and columns: scheme, server, port, user, path, query, fragment. } \description{ Parse a url into its component pieces. } \examples{ url_parse("http://had.co.nz/") url_parse("http://had.co.nz:1234/") url_parse("http://had.co.nz:1234/?a=1&b=2") url_parse("http://had.co.nz:1234/?a=1&b=2#def") } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_missing.Rd�����������������������������������������������������������������������������0000644�0001762�0000144�00000000406�14727652467�014553� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_missing.R \name{xml_missing} \alias{xml_missing} \title{Construct an missing xml object} \usage{ xml_missing() } \description{ Construct an missing xml object } \keyword{internal} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/as_xml_document.Rd�������������������������������������������������������������������������0000644�0001762�0000144�00000001671�14727652467�015410� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/as_xml_document.R \name{as_xml_document} \alias{as_xml_document} \title{Coerce a R list to xml nodes.} \usage{ as_xml_document(x, ...) } \arguments{ \item{x}{A document, node, or node set.} \item{...}{Needed for compatibility with generic. Unused.} } \description{ This turns an R list into the equivalent XML document. Not all R lists will produce valid XML, in particular there can only be one root node and all child nodes need to be named (or empty) lists. R attributes become XML attributes and R names become XML node names. } \examples{ as_xml_document(list(x = list())) # Nesting multiple nodes as_xml_document(list(foo = list(bar = list(baz = list())))) # attributes are stored as R attributes as_xml_document(list(foo = structure(list(), id = "a"))) as_xml_document(list(foo = list( bar = structure(list(), id = "a"), bar = structure(list(), id = "b") ))) } �����������������������������������������������������������������������xml2/man/xml_children.Rd����������������������������������������������������������������������������0000644�0001762�0000144�00000004507�14727652467�014700� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_children.R \name{xml_children} \alias{xml_children} \alias{xml_child} \alias{xml_contents} \alias{xml_parents} \alias{xml_siblings} \alias{xml_parent} \alias{xml_length} \alias{xml_root} \title{Navigate around the family tree.} \usage{ xml_children(x) xml_child(x, search = 1, ns = xml_ns(x)) xml_contents(x) xml_parents(x) xml_siblings(x) xml_parent(x) xml_length(x, only_elements = TRUE) xml_root(x) } \arguments{ \item{x}{A document, node, or node set.} \item{search}{For \code{xml_child}, either the child number to return (by position), or the name of the child node to return. If there are multiple child nodes with the same name, the first will be returned} \item{ns}{Optionally, a named vector giving prefix-url pairs, as produced by \code{\link[=xml_ns]{xml_ns()}}. If provided, all names will be explicitly qualified with the ns prefix, i.e. if the element \code{bar} is defined in namespace \code{foo}, it will be called \code{foo:bar}. (And similarly for attributes). Default namespaces must be given an explicit name. The ns is ignored when using \code{\link[=xml_name<-]{xml_name<-()}} and \code{\link[=xml_set_name]{xml_set_name()}}.} \item{only_elements}{For \code{xml_length}, should it count all children, or just children that are elements (the default)?} } \value{ A node or nodeset (possibly empty). Results are always de-duplicated. } \description{ \code{xml_children} returns only elements, \code{xml_contents} returns all nodes. \code{xml_length} returns the number of children. \code{xml_parent} returns the parent node, \code{xml_parents} returns all parents up to the root. \code{xml_siblings} returns all nodes at the same level. \code{xml_child} makes it easy to specify a specific child to return. } \examples{ x <- read_xml("<foo> <bar><boo /></bar> <baz/> </foo>") xml_children(x) xml_children(xml_children(x)) xml_siblings(xml_children(x)[[1]]) # Note the each unique node only appears once in the output xml_parent(xml_children(x)) # Mixed content x <- read_xml("<foo> a <b/> c <d>e</d> f</foo>") # Childen gets the elements, contents gets all node types xml_children(x) xml_contents(x) xml_length(x) xml_length(x, only_elements = FALSE) # xml_child makes it easier to select specific children xml_child(x) xml_child(x, 2) xml_child(x, "baz") } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/url_escape.Rd������������������������������������������������������������������������������0000644�0001762�0000144�00000001010�14727652467�014334� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_url.R \name{url_escape} \alias{url_escape} \alias{url_unescape} \title{Escape and unescape urls.} \usage{ url_escape(x, reserved = "") url_unescape(x) } \arguments{ \item{x}{A character vector of urls.} \item{reserved}{A string containing additional characters to avoid escaping.} } \description{ Escape and unescape urls. } \examples{ url_escape("a b c") url_escape("a b c", "") url_unescape("a\%20b\%2fc") url_unescape("\%C2\%B5") } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_cdata.Rd�������������������������������������������������������������������������������0000644�0001762�0000144�00000000614�14727652467�014157� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/classes.R \name{xml_cdata} \alias{xml_cdata} \title{Construct a cdata node} \usage{ xml_cdata(content) } \arguments{ \item{content}{The CDATA content, does not include \verb{<![CDATA[}} } \description{ Construct a cdata node } \examples{ x <- xml_new_root("root") xml_add_child(x, xml_cdata("<d/>")) as.character(x) } ��������������������������������������������������������������������������������������������������������������������xml2/man/as_list.Rd���������������������������������������������������������������������������������0000644�0001762�0000144�00000003455�14727652467�013667� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/as_list.R \name{as_list} \alias{as_list} \title{Coerce xml nodes to a list.} \usage{ as_list(x, ns = character(), ...) } \arguments{ \item{x}{A document, node, or node set.} \item{ns}{Optionally, a named vector giving prefix-url pairs, as produced by \code{\link[=xml_ns]{xml_ns()}}. If provided, all names will be explicitly qualified with the ns prefix, i.e. if the element \code{bar} is defined in namespace \code{foo}, it will be called \code{foo:bar}. (And similarly for attributes). Default namespaces must be given an explicit name. The ns is ignored when using \code{\link[=xml_name<-]{xml_name<-()}} and \code{\link[=xml_set_name]{xml_set_name()}}.} \item{...}{Needed for compatibility with generic. Unused.} } \description{ This turns an XML document (or node or nodeset) into the equivalent R list. Note that this is \code{as_list()}, not \code{as.list()}: \code{lapply()} automatically calls \code{as.list()} on its inputs, so we can't override the default. } \details{ \code{as_list} currently only handles the four most common types of children that an element might have: \itemize{ \item Other elements, converted to lists. \item Attributes, stored as R attributes. Attributes that have special meanings in R (\code{\link[=class]{class()}}, \code{\link[=comment]{comment()}}, \code{\link[=dim]{dim()}}, \code{\link[=dimnames]{dimnames()}}, \code{\link[=names]{names()}}, \code{\link[=row.names]{row.names()}} and \code{\link[=tsp]{tsp()}}) are escaped with '.' \item Text, stored as a character vector. } } \examples{ as_list(read_xml("<foo> a <b /><c><![CDATA[<d></d>]]></c></foo>")) as_list(read_xml("<foo> <bar><baz /></bar> </foo>")) as_list(read_xml("<foo id = 'a'></foo>")) as_list(read_xml("<foo><bar id='a'/><bar id='b'/></foo>")) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_structure.Rd���������������������������������������������������������������������������0000644�0001762�0000144�00000002505�14727652467�015144� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_structure.R \name{xml_structure} \alias{xml_structure} \alias{html_structure} \title{Show the structure of an html/xml document.} \usage{ xml_structure(x, indent = 2, file = "") html_structure(x, indent = 2, file = "") } \arguments{ \item{x}{HTML/XML document (or part there of)} \item{indent}{Number of spaces to ident} \item{file}{A \link[base]{connection}, or a character string naming the file to print to. If \code{""} (the default), \code{cat} prints to the standard output connection, the console unless redirected by \code{\link[base]{sink}}. If it is \code{"|cmd"}, the output is piped to the command given by \file{cmd}, by opening a pipe connection. } } \description{ Show the structure of an html/xml document without displaying any of the values. This is useful if you want to get a high level view of the way a document is organised. Compared to \code{xml_structure}, \code{html_structure} prints the id and class attributes. } \examples{ xml_structure(read_xml("<a><b><c/><c/></b><d/></a>")) rproj <- read_html(system.file("extdata", "r-project.html", package = "xml2")) xml_structure(rproj) xml_structure(xml_find_all(rproj, ".//p")) h <- read_html("<body><p id = 'a'></p><p class = 'c d'></p></body>") html_structure(h) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_path.Rd��������������������������������������������������������������������������������0000644�0001762�0000144�00000000751�14727652467�014041� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_path.R \name{xml_path} \alias{xml_path} \title{Retrieve the xpath to a node} \usage{ xml_path(x) } \arguments{ \item{x}{A document, node, or node set.} } \value{ A character vector. } \description{ This is useful when you want to figure out where nodes matching an xpath expression live in a document. } \examples{ x <- read_xml("<foo><bar><baz /></bar><baz /></foo>") xml_path(xml_find_all(x, ".//baz")) } �����������������������xml2/man/url_absolute.Rd����������������������������������������������������������������������������0000644�0001762�0000144�00000001544�14727652467�014726� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_url.R \name{url_absolute} \alias{url_absolute} \alias{url_relative} \title{Convert between relative and absolute urls.} \usage{ url_absolute(x, base) url_relative(x, base) } \arguments{ \item{x}{A character vector of urls relative to that base} \item{base}{A string giving a base url.} } \value{ A character vector of urls } \description{ Convert between relative and absolute urls. } \examples{ url_absolute(c(".", "..", "/", "/x"), "http://hadley.nz/a/b/c/d") url_relative("http://hadley.nz/a/c", "http://hadley.nz") url_relative("http://hadley.nz/a/c", "http://hadley.nz/") url_relative("http://hadley.nz/a/c", "http://hadley.nz/a/b") url_relative("http://hadley.nz/a/c", "http://hadley.nz/a/b/") } \seealso{ \code{\link{xml_url}} to retrieve the URL associated with a document } ������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_new_document.Rd������������������������������������������������������������������������0000644�0001762�0000144�00000002576�14727652467�015603� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_modify.R \name{xml_new_document} \alias{xml_new_document} \alias{xml_new_root} \title{Create a new document, possibly with a root node} \usage{ xml_new_document(version = "1.0", encoding = "UTF-8") xml_new_root( .value, ..., .copy = inherits(.value, "xml_node"), .version = "1.0", .encoding = "UTF-8" ) } \arguments{ \item{version}{The version number of the document.} \item{encoding}{The character encoding to use in the document. The default encoding is \sQuote{UTF-8}. Available encodings are specified at \url{http://xmlsoft.org/html/libxml-encoding.html#xmlCharEncoding}.} \item{.value}{node to insert.} \item{...}{If named attributes or namespaces to set on the node, if unnamed text to assign to the node.} \item{.copy}{whether to copy the \code{.value} before replacing. If this is \code{FALSE} then the node will be moved from it's current location.} \item{.version}{The version number of the document, passed to \code{xml_new_document(version)}.} \item{.encoding}{The encoding of the document, passed to \code{xml_new_document(encoding)}.} } \value{ A \code{xml_document} object. } \description{ \code{xml_new_document} creates only a new document without a root node. In most cases you should instead use \code{xml_new_root}, which creates a new document and assigns the root node in one step. } ����������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_set_namespace.Rd�����������������������������������������������������������������������0000644�0001762�0000144�00000000727�14727652467�015717� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_modify.R \name{xml_set_namespace} \alias{xml_set_namespace} \title{Set the node's namespace} \usage{ xml_set_namespace(.x, prefix = "", uri = "") } \arguments{ \item{.x}{a node} \item{prefix}{The namespace prefix to use} \item{uri}{The namespace URI to use} } \value{ the node (invisibly) } \description{ The namespace to be set must be already defined in one of the node's ancestors. } �����������������������������������������xml2/man/write_xml.Rd�������������������������������������������������������������������������������0000644�0001762�0000144�00000002745�14727652467�014244� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_write.R \name{write_xml} \alias{write_xml} \alias{write_xml.xml_document} \alias{write_html} \alias{write_html.xml_document} \title{Write XML or HTML to disk.} \usage{ write_xml(x, file, ...) \method{write_xml}{xml_document}(x, file, ..., options = "format", encoding = "UTF-8") write_html(x, file, ...) \method{write_html}{xml_document}(x, file, ..., options = "format", encoding = "UTF-8") } \arguments{ \item{x}{A document or node to write to disk. It's not possible to save nodesets containing more than one node.} \item{file}{Path to file or connection to write to.} \item{...}{additional arguments passed to methods.} \item{options}{default: \sQuote{format}. Zero or more of \Sexpr[results=rd, stage=build]{xml2:::describe_options(xml2:::xml_save_options())}} \item{encoding}{The character encoding to use in the document. The default encoding is \sQuote{UTF-8}. Available encodings are specified at \url{http://xmlsoft.org/html/libxml-encoding.html#xmlCharEncoding}.} } \description{ This writes out both XML and normalised HTML. The default behavior will output the same format which was read. If you want to force output pass \code{option = "as_xml"} or \code{option = "as_html"} respectively. } \examples{ h <- read_html("<p>Hi!</p>") tmp <- tempfile(fileext = ".xml") write_xml(h, tmp, options = "format") readLines(tmp) # write formatted HTML output write_html(h, tmp, options = "format") readLines(tmp) } ���������������������������xml2/man/xml_text.Rd��������������������������������������������������������������������������������0000644�0001762�0000144�00000002306�14727652467�014067� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_text.R \name{xml_text} \alias{xml_text} \alias{xml_text<-} \alias{xml_set_text} \alias{xml_double} \alias{xml_integer} \title{Extract or modify the text} \usage{ xml_text(x, trim = FALSE) xml_text(x) <- value xml_set_text(x, value) xml_double(x) xml_integer(x) } \arguments{ \item{x}{A document, node, or node set.} \item{trim}{If \code{TRUE} will trim leading and trailing spaces.} \item{value}{character vector with replacement text.} } \value{ A character vector, the same length as x. } \description{ \code{xml_text} returns a character vector, \code{xml_double} returns a numeric vector, \code{xml_integer} returns an integer vector. } \examples{ x <- read_xml("<p>This is some text. This is <b>bold!</b></p>") xml_text(x) xml_text(xml_children(x)) x <- read_xml("<x>This is some text. <x>This is some nested text.</x></x>") xml_text(x) xml_text(xml_find_all(x, "//x")) x <- read_xml("<p> Some text </p>") xml_text(x, trim = TRUE) # xml_double() and xml_integer() are useful for extracting numeric attributes x <- read_xml("<plot><point x='1' y='2' /><point x='2' y='1' /></plot>") xml_integer(xml_find_all(x, "//@x")) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/figures/�����������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14727652467�013377� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/figures/lifecycle-questioning.svg����������������������������������������������������������0000644�0001762�0000144�00000002444�14727652467�020426� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="20" role="img" aria-label="lifecycle: questioning"> <title>lifecycle: questioning lifecycle questioning xml2/man/figures/lifecycle-stable.svg0000644000176200001440000000247214727652467017334 0ustar liggesusers lifecycle: stable lifecycle stable xml2/man/figures/lifecycle-experimental.svg0000644000176200001440000000245014727652467020553 0ustar liggesusers lifecycle: experimental lifecycle experimental xml2/man/figures/lifecycle-deprecated.svg0000644000176200001440000000244014727652467020155 0ustar liggesusers lifecycle: deprecated lifecycle deprecated xml2/man/figures/lifecycle-superseded.svg0000644000176200001440000000244014727652467020220 0ustar liggesusers lifecycle: superseded lifecycle superseded xml2/man/figures/lifecycle-archived.svg0000644000176200001440000000243014727652467017641 0ustar liggesusers lifecycle: archived lifecycle archived xml2/man/figures/lifecycle-defunct.svg0000644000176200001440000000242414727652467017507 0ustar liggesusers lifecycle: defunct lifecycle defunct xml2/man/figures/lifecycle-soft-deprecated.svg0000644000176200001440000000246614727652467021136 0ustar liggesusers lifecycle: soft-deprecated lifecycle soft-deprecated xml2/man/figures/lifecycle-maturing.svg0000644000176200001440000000243014727652467017702 0ustar liggesusers lifecycle: maturing lifecycle maturing xml2/man/oldclass.Rd0000644000176200001440000000121514727652467014025 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/S4.R \name{xml_document-class} \alias{xml_document-class} \alias{xml_missing-class} \alias{xml_node-class} \alias{xml_nodeset-class} \title{Register S4 classes} \description{ Classes are exported so they can be re-used within S4 classes, see \code{\link[methods:setOldClass]{methods::setOldClass()}}. \itemize{ \item \code{xml_document}: a complete document. \item \code{xml_nodeset}: a \emph{set} of nodes within a document. \item \code{xml_missing}: a missing object, e.g. for an empty result set. \item \code{xml_node}: a single node in a document. } } \keyword{internal} xml2/man/xml_validate.Rd0000644000176200001440000000123014727652467014667 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_schema.R \name{xml_validate} \alias{xml_validate} \title{Validate XML schema} \usage{ xml_validate(x, schema) } \arguments{ \item{x}{A document, node, or node set.} \item{schema}{an XML document containing the schema} } \value{ TRUE or FALSE } \description{ Validate an XML document against an XML 1.0 schema. } \examples{ # Example from https://msdn.microsoft.com/en-us/library/ms256129(v=vs.110).aspx doc <- read_xml(system.file("extdata/order-doc.xml", package = "xml2")) schema <- read_xml(system.file("extdata/order-schema.xml", package = "xml2")) xml_validate(doc, schema) } xml2/man/xml_url.Rd0000644000176200001440000000102514727652467013702 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_url.R \name{xml_url} \alias{xml_url} \title{The URL of an XML document} \usage{ xml_url(x) } \arguments{ \item{x}{A node or document.} } \value{ A character vector of length 1. Returns \code{NA} if the name is not set. } \description{ This is useful for interpreting relative urls with \code{\link[=url_relative]{url_relative()}}. } \examples{ catalog <- read_xml(xml2_example("cd_catalog.xml")) xml_url(catalog) x <- read_xml("") xml_url(x) } xml2/man/xml2_example.Rd0000644000176200001440000000066314727652467014624 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{xml2_example} \alias{xml2_example} \title{Get path to a xml2 example} \usage{ xml2_example(path = NULL) } \arguments{ \item{path}{Name of file. If \code{NULL}, the example files will be listed.} } \description{ xml2 comes bundled with a number of sample files in its \sQuote{inst/extdata} directory. This function makes them easy to access. } xml2/man/xml_attr.Rd0000644000176200001440000000612414727652467014057 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_attr.R \name{xml_attr} \alias{xml_attr} \alias{xml_has_attr} \alias{xml_attrs} \alias{xml_attr<-} \alias{xml_set_attr} \alias{xml_attrs<-} \alias{xml_set_attrs} \title{Retrieve an attribute.} \usage{ xml_attr(x, attr, ns = character(), default = NA_character_) xml_has_attr(x, attr, ns = character()) xml_attrs(x, ns = character()) xml_attr(x, attr, ns = character()) <- value xml_set_attr(x, attr, value, ns = character()) xml_attrs(x, ns = character()) <- value xml_set_attrs(x, value, ns = character()) } \arguments{ \item{x}{A document, node, or node set.} \item{attr}{Name of attribute to extract.} \item{ns}{Optionally, a named vector giving prefix-url pairs, as produced by \code{\link[=xml_ns]{xml_ns()}}. If provided, all names will be explicitly qualified with the ns prefix, i.e. if the element \code{bar} is defined in namespace \code{foo}, it will be called \code{foo:bar}. (And similarly for attributes). Default namespaces must be given an explicit name. The ns is ignored when using \code{\link[=xml_name<-]{xml_name<-()}} and \code{\link[=xml_set_name]{xml_set_name()}}.} \item{default}{Default value to use when attribute is not present.} \item{value}{character vector of new value.} } \value{ \code{xml_attr()} returns a character vector. \code{NA} is used to represent of attributes that aren't defined. \code{xml_has_attr()} returns a logical vector. \code{xml_attrs()} returns a named character vector if \code{x} x is single node, or a list of character vectors if given a nodeset } \description{ \code{xml_attrs()} retrieves all attributes values as a named character vector, \verb{xml_attrs() <-} or \code{xml_set_attrs()} sets all attribute values. \code{xml_attr()} retrieves the value of single attribute and \verb{xml_attr() <-} or \code{xml_set_attr()} modifies its value. If the attribute doesn't exist, it will return \code{default}, which defaults to \code{NA}. \code{xml_has_attr()} tests if an attribute is present. } \examples{ x <- read_xml("") xml_attr(x, "id") xml_attr(x, "apple") xml_attrs(x) kids <- xml_children(x) kids xml_attr(kids, "id") xml_has_attr(kids, "id") xml_attrs(kids) # Missing attributes give missing values xml_attr(xml_children(x), "d") xml_has_attr(xml_children(x), "d") # If the document has a namespace, use the ns argument and # qualified attribute names x <- read_xml(' ') doc <- xml_children(x)[[1]] ns <- xml_ns(x) xml_attrs(doc) xml_attrs(doc, ns) # If you don't supply a ns spec, you get the first matching attribute xml_attr(doc, "id") xml_attr(doc, "b:id", ns) xml_attr(doc, "id", ns) # Can set a single attribute with `xml_attr() <-` or `xml_set_attr()` xml_attr(doc, "id") <- "one" xml_set_attr(doc, "id", "two") # Or set multiple attributes with `xml_attrs()` or `xml_set_attrs()` xml_attrs(doc) <- c("b:id" = "one", "f:id" = "two", "id" = "three") xml_set_attrs(doc, c("b:id" = "one", "f:id" = "two", "id" = "three")) } xml2/DESCRIPTION0000644000176200001440000000401714765101672012655 0ustar liggesusersPackage: xml2 Title: Parse XML Version: 1.3.8 Authors@R: c( person("Hadley", "Wickham", role = "aut"), person("Jim", "Hester", role = "aut"), person("Jeroen", "Ooms", email = "jeroenooms@gmail.com", role = c("aut", "cre")), person("Posit Software, PBC", role = c("cph", "fnd")), person("R Foundation", role = "ctb", comment = "Copy of R-project homepage cached as example") ) Description: Bindings to 'libxml2' for working with XML data using a simple, consistent interface based on 'XPath' expressions. Also supports XML schema validation; for 'XSLT' transformations see the 'xslt' package. License: MIT + file LICENSE URL: https://xml2.r-lib.org, https://r-lib.r-universe.dev/xml2 BugReports: https://github.com/r-lib/xml2/issues Depends: R (>= 3.6.0) Imports: cli, methods, rlang (>= 1.1.0) Suggests: covr, curl, httr, knitr, magrittr, mockery, rmarkdown, testthat (>= 3.2.0), xslt VignetteBuilder: knitr Config/Needs/website: tidyverse/tidytemplate Encoding: UTF-8 RoxygenNote: 7.2.3 SystemRequirements: libxml2: libxml2-dev (deb), libxml2-devel (rpm) Collate: 'S4.R' 'as_list.R' 'xml_parse.R' 'as_xml_document.R' 'classes.R' 'format.R' 'import-standalone-obj-type.R' 'import-standalone-purrr.R' 'import-standalone-types-check.R' 'init.R' 'nodeset_apply.R' 'paths.R' 'utils.R' 'xml2-package.R' 'xml_attr.R' 'xml_children.R' 'xml_document.R' 'xml_find.R' 'xml_missing.R' 'xml_modify.R' 'xml_name.R' 'xml_namespaces.R' 'xml_node.R' 'xml_nodeset.R' 'xml_path.R' 'xml_schema.R' 'xml_serialize.R' 'xml_structure.R' 'xml_text.R' 'xml_type.R' 'xml_url.R' 'xml_write.R' 'zzz.R' Config/testthat/edition: 3 NeedsCompilation: yes Packaged: 2025-03-14 14:37:00 UTC; jeroen Author: Hadley Wickham [aut], Jim Hester [aut], Jeroen Ooms [aut, cre], Posit Software, PBC [cph, fnd], R Foundation [ctb] (Copy of R-project homepage cached as example) Maintainer: Jeroen Ooms Repository: CRAN Date/Publication: 2025-03-14 19:30:02 UTC