Skip to content

Commit f272b7f

Browse files
committed
Implement xml_attr
1 parent 0cc03f7 commit f272b7f

File tree

7 files changed

+93
-1
lines changed

7 files changed

+93
-1
lines changed

NAMESPACE

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
S3method(print,xml_doc)
44
S3method(print,xml_node)
55
S3method(print,xml_nodeset)
6+
S3method(xml_attr,xml_doc)
7+
S3method(xml_attr,xml_node)
8+
S3method(xml_attr,xml_nodeset)
69
S3method(xml_children,xml_doc)
710
S3method(xml_children,xml_node)
811
S3method(xml_children,xml_nodeset)
@@ -15,6 +18,7 @@ S3method(xml_root,xml_nodeset)
1518
S3method(xml_text,xml_doc)
1619
S3method(xml_text,xml_node)
1720
S3method(xml_text,xml_nodeset)
21+
export(xml_attr)
1822
export(xml_children)
1923
export(xml_name)
2024
export(xml_parse)

R/RcppExports.R

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ node_text <- function(node) {
4545
.Call('xml2_node_text', PACKAGE = 'xml2', node)
4646
}
4747

48+
node_attr <- function(node, name) {
49+
.Call('xml2_node_attr', PACKAGE = 'xml2', node, name)
50+
}
51+
4852
node_format <- function(doc, node, format = TRUE, indent = 0L) {
4953
.Call('xml2_node_format', PACKAGE = 'xml2', doc, node, format, indent)
5054
}

R/xml_attr.R

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#' Retrieve an attribute.
2+
#'
3+
#' @inheritParams xml_name
4+
#' @param attr Name of attribute to extract.
5+
#' @return A character vector. If an attribute is not presented, its
6+
#' value will be missing.
7+
#' @export
8+
#' @examples
9+
#' x <- xml_parse("<root id='1'><child id ='a' /><child id='b' d='b'/></root>")
10+
#' xml_attr(x, "id")
11+
#' xml_attr(xml_children(x), "id")
12+
#' xml_attr(xml_children(x), "d")
13+
xml_attr <- function(x, attr, ...) {
14+
UseMethod("xml_attr")
15+
}
16+
17+
#' @export
18+
xml_attr.xml_node <- function(x, attr, ...) {
19+
node_attr(x$node, attr)
20+
}
21+
22+
#' @export
23+
xml_attr.xml_doc <- function(x, attr, ...) {
24+
node_attr(doc_root(x$doc), attr)
25+
}
26+
27+
#' @export
28+
xml_attr.xml_nodeset <- function(x, attr, ...) {
29+
vapply(x, xml_attr, attr = attr, ..., FUN.VALUE = character(1))
30+
}

man/xml_attr.Rd

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
% Generated by roxygen2 (4.1.0): do not edit by hand
2+
% Please edit documentation in R/xml_attr.R
3+
\name{xml_attr}
4+
\alias{xml_attr}
5+
\title{Retrieve an attribute.}
6+
\usage{
7+
xml_attr(x, attr, ...)
8+
}
9+
\arguments{
10+
\item{x}{A document, node, or node set.}
11+
12+
\item{attr}{Name of attribute to extract.}
13+
14+
\item{...}{Additional arguments passed down to methods. (Not currently used).}
15+
}
16+
\value{
17+
A character vector. If an attribute is not presented, its
18+
value will be missing.
19+
}
20+
\description{
21+
Retrieve an attribute.
22+
}
23+
\examples{
24+
x <- xml_parse("<root id='1'><child id ='a' /><child id='b' d='b'/></root>")
25+
xml_attr(x, "id")
26+
xml_attr(xml_children(x), "id")
27+
xml_attr(xml_children(x), "d")
28+
}
29+

src/RcppExports.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,18 @@ BEGIN_RCPP
135135
return __result;
136136
END_RCPP
137137
}
138+
// node_attr
139+
CharacterVector node_attr(XPtrNode node, std::string name);
140+
RcppExport SEXP xml2_node_attr(SEXP nodeSEXP, SEXP nameSEXP) {
141+
BEGIN_RCPP
142+
Rcpp::RObject __result;
143+
Rcpp::RNGScope __rngScope;
144+
Rcpp::traits::input_parameter< XPtrNode >::type node(nodeSEXP);
145+
Rcpp::traits::input_parameter< std::string >::type name(nameSEXP);
146+
__result = Rcpp::wrap(node_attr(node, name));
147+
return __result;
148+
END_RCPP
149+
}
138150
// node_format
139151
CharacterVector node_format(XPtrDoc doc, XPtrNode node, bool format = true, int indent = 0);
140152
RcppExport SEXP xml2_node_format(SEXP docSEXP, SEXP nodeSEXP, SEXP formatSEXP, SEXP indentSEXP) {

src/xml2_node.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@ CharacterVector node_name(XPtrNode node) {
1212
CharacterVector node_text(XPtrNode node) {
1313
xmlChar* s = xmlNodeGetContent(node.get());
1414
CharacterVector out = xmlCharToRChar(s);
15+
if (s != NULL)
16+
xmlFree(s);
17+
18+
return out;
19+
}
20+
21+
// [[Rcpp::export]]
22+
CharacterVector node_attr(XPtrNode node, std::string name) {
23+
xmlChar* s = xmlGetProp(node.get(), (xmlChar*) name.c_str());
24+
25+
CharacterVector out = xmlCharToRChar(s);
26+
if (s != NULL)
27+
xmlFree(s);
1528

1629
return out;
1730
}

src/xml2_utils.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
inline Rcpp::CharacterVector xmlCharToRChar(const xmlChar* x) {
88
if (x == NULL)
9-
Rcpp::stop("Null string");
9+
return Rcpp::CharacterVector::create(NA_STRING);
1010

1111
Rcpp::CharacterVector out(1);
1212
out[0] = Rf_mkCharCE((char*) x, CE_UTF8);

0 commit comments

Comments
 (0)