Replies: 1 comment
-
Function to reorder xml children // [[Rcpp::export]]
SEXP xml_order_children1(XPtrXML node, std::string child, const std::vector<int>& order, bool pointer) {
uint32_t pugi_format_flags = pugi_format(node);
pugi::xml_node root = node->child(child.c_str());
std::vector<pugi::xml_node> children;
for (pugi::xml_node child : root.children()) {
if (child.type() == pugi::node_element) {
children.push_back(child);
}
}
if (order.size() != children.size()) {
Rcpp::stop("Order size (%d) does not match the number of children (%d).",
order.size(), children.size());
}
std::vector<pugi::xml_node> reordered_children(order.size());
for (size_t i = 0; i < order.size(); ++i) {
if (order[i] < 0 || static_cast<size_t>(order[i]) >= children.size()) {
Rcpp::stop("Invalid order index: %d", order[i]);
}
reordered_children[i] = children[order[i]];
}
root.remove_children();
for (const auto& child : reordered_children) {
root.append_copy(child);
}
if (pointer) {
return node;
} else {
std::ostringstream oss;
root.print(oss, " ", pugi_format_flags);
return Rcpp::wrap(Rcpp::String(oss.str()));
}
} #' order xml children in node
#' @param xml_node an xml structure
#' @param level the xml root
#' @param order the wanted order as numeric
#' @param pointer pointer
#' @param ... additional arguments passed to `read_xml()`
#' @examples
#' xml <- "<a><b/><c/><d/></a>"
#' xml_order_children(xml, "a", c(3, 2, 1))
#' @export
xml_order_children <- function(xml_node, level, order, pointer = FALSE, ...) {
if (missing(xml_node) || missing(level) || missing(order))
stop("need xml_node, level, and order")
if (!inherits(xml_node, "pugi_xml")) xml_node <- read_xml(xml_node, ...)
assert_class(level, "character")
if (!xml_node_name(xml_node) %in% level)
stop("level not found")
order <- order - 1L
xml_order_children1(node = xml_node, child = level, order = order, pointer = pointer)
} test_that("xml_order_children works", {
xml <- "<a><b/><c/><d/></a>"
exp <- "<a><d/><c/><b/></a>"
got <- xml_order_children(xml, "a", c(3, 2, 1))
expect_equal(exp, got)
got <- xml_order_children(xml, "a", c(3, 2, 1), pointer = TRUE)
expect_equal(TRUE, inherits(got, "pugi_xml"))
expect_error(xml_order_children(xml, "b", c(3, 2, 1)), "level not found")
expect_error(xml_order_children(xml, "a", c(2, 1)), "does not match the number of children")
expect_error(xml_order_children(xml, "a", c(2, 1, 0)), "Invalid order index")
expect_error(xml_order_children(xml, c(2, 1, 0)), "need xml_node, level, and order")
}) |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
The following matches a few
xml2
functions used inmschart
. Not sure if we really have a need for any of this, but I was curious what is used and not currently supported by us. We have a couple of functions that provide similar things, but a) I've only implemented nesting of 3 nodes (mschart
requires more).Beta Was this translation helpful? Give feedback.
All reactions