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