diff --git a/NEWS.md b/NEWS.md index 37ac7995..1c9ceff3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # xml2 (development version) +* `xml_parent()` now supports passing `deduplicate = TRUE` to avoid de-duplication of nodes in the returned nodeset. + * `xml_find_all.xml_nodeset()` gains a `flatten` argument to control whether to return a single nodeset or a list of nodesets (#311, @jakejh) * `write_xml()` and `write_html()` now return NULL invisibly, as they did prior to version 1.3.0 (#307) diff --git a/R/classes.R b/R/classes.R index 14a9b722..a13e5914 100644 --- a/R/classes.R +++ b/R/classes.R @@ -81,10 +81,10 @@ xml_nodeset <- function(nodes = list(), deduplicate = TRUE) { #' @param nodes A list (possible nested) of external pointers to nodes #' @return a nodeset #' @noRd -make_nodeset <- function(nodes, doc) { +make_nodeset <- function(nodes, doc, ...) { nodes <- unlist(nodes, recursive = FALSE) - xml_nodeset(lapply(nodes, xml_node, doc = doc)) + xml_nodeset(lapply(nodes, xml_node, doc = doc), ...) } #' @export @@ -147,7 +147,7 @@ nodeset_apply.xml_missing <- function(x, fun, ...) { } #' @export -nodeset_apply.xml_nodeset <- function(x, fun, ...) { +nodeset_apply.xml_nodeset <- function(x, fun, ..., deduplicate = TRUE) { if (length(x) == 0) return(xml_nodeset()) @@ -159,7 +159,7 @@ nodeset_apply.xml_nodeset <- function(x, fun, ...) { res[!is_missing] <- lapply(x[!is_missing], function(x) fun(x$node, ...)) } - make_nodeset(res, x[[1]]$doc) + make_nodeset(res, x[[1]]$doc, deduplicate = deduplicate) } #' @export diff --git a/R/xml_children.R b/R/xml_children.R index faabd857..e9926cc0 100644 --- a/R/xml_children.R +++ b/R/xml_children.R @@ -24,6 +24,9 @@ #' # Note the each unique node only appears once in the output #' xml_parent(xml_children(x)) #' +#' # But you avoid this deduplication if needed +#' xml_parent(xml_children(x), deduplicate = FALSE) +#' #' # Mixed content #' x <- read_xml(" a c e f") #' # Childen gets the elements, contents gets all node types @@ -37,8 +40,8 @@ #' xml_child(x) #' xml_child(x, 2) #' xml_child(x, "baz") -xml_children <- function(x) { - nodeset_apply(x, function(x) .Call(node_children, x, TRUE)) +xml_children <- function(x, ...) { + nodeset_apply(x, function(x) .Call(node_children, x, TRUE), ...) } #' @export @@ -65,8 +68,8 @@ xml_contents <- function(x) { #' @export #' @rdname xml_children -xml_parents <- function(x) { - nodeset_apply(x, function(x) .Call(node_parents, x)) +xml_parents <- function(x, ...) { + nodeset_apply(x, function(x) .Call(node_parents, x), ...) } #' @export @@ -77,23 +80,23 @@ xml_siblings <- function(x) { #' @export #' @rdname xml_children -xml_parent <- function(x) { +xml_parent <- function(x, ...) { UseMethod("xml_parent") } #' @export -xml_parent.xml_missing <- function(x) { +xml_parent.xml_missing <- function(x, ...) { xml_missing() } #' @export -xml_parent.xml_node <- function(x) { +xml_parent.xml_node <- function(x, ...) { xml_node(.Call(node_parent, x$node), x$doc) } #' @export -xml_parent.xml_nodeset <- function(x) { - nodeset_apply(x, function(x) .Call(node_parent, x)) +xml_parent.xml_nodeset <- function(x, ...) { + nodeset_apply(x, function(x) .Call(node_parent, x), ...) } diff --git a/man/xml_children.Rd b/man/xml_children.Rd index 076182f6..7a3d0d74 100644 --- a/man/xml_children.Rd +++ b/man/xml_children.Rd @@ -11,17 +11,17 @@ \alias{xml_root} \title{Navigate around the family tree.} \usage{ -xml_children(x) +xml_children(x, ...) xml_child(x, search = 1, ns = xml_ns(x)) xml_contents(x) -xml_parents(x) +xml_parents(x, ...) xml_siblings(x) -xml_parent(x) +xml_parent(x, ...) xml_length(x, only_elements = TRUE) @@ -65,6 +65,9 @@ xml_siblings(xml_children(x)[[1]]) # Note the each unique node only appears once in the output xml_parent(xml_children(x)) +# But you can also get the repeated nodes if needed +xml_parent(xml_children(x), deduplicate = FALSE) + # Mixed content x <- read_xml(" a c e f") # Childen gets the elements, contents gets all node types