@@ -23,24 +23,24 @@ class XmlSeeker {
2323 context_->node = node;
2424 }
2525
26- void registerNamespace (SEXP nsMap) {
27- R_xlen_t n = Rf_xlength ( nsMap);
26+ void registerNamespace (cpp11::strings nsMap) {
27+ R_xlen_t n = nsMap. size ( );
2828 if (n == 0 ) {
2929 return ;
3030 }
3131
32- SEXP prefix = Rf_getAttrib ( nsMap, R_NamesSymbol );
32+ cpp11::strings prefix = nsMap. names ( );
3333
3434 for (int i = 0 ; i < n; ++i) {
35- xmlChar* prefixI = (xmlChar*) CHAR (STRING_ELT ( prefix, i) );
36- xmlChar* urlI = (xmlChar*) CHAR (STRING_ELT ( nsMap, i) );
35+ xmlChar* prefixI = (xmlChar*) CHAR (prefix[i] );
36+ xmlChar* urlI = (xmlChar*) CHAR (nsMap[i] );
3737
3838 if (xmlXPathRegisterNs (context_, prefixI, urlI) != 0 )
39- Rf_error (" Failed to register namespace (%s <-> %s)" , prefixI, urlI);
39+ cpp11::stop (" Failed to register namespace (%s <-> %s)" , prefixI, urlI);
4040 }
4141 }
4242
43- SEXP search (const char * xpath, int num_results) {
43+ cpp11::sexp search (const char * xpath, int num_results) {
4444 result_ = xmlXPathEval ((const xmlChar*)xpath, context_);
4545 if (result_ == NULL ) {
4646 SEXP ret = PROTECT (Rf_allocVector (VECSXP, 0 ));
@@ -61,34 +61,29 @@ class XmlSeeker {
6161 }
6262 int n = std::min (result_->nodesetval ->nodeNr , num_results);
6363
64- SEXP out = PROTECT ( Rf_allocVector (VECSXP, n) );
64+ cpp11::writable::list out (n );
6565
66- SEXP names = PROTECT (Rf_allocVector (STRSXP, 2 ));
67- SET_STRING_ELT (names, 0 , Rf_mkChar (" node" ));
68- SET_STRING_ELT (names, 1 , Rf_mkChar (" doc" ));
66+ cpp11::strings names ({" node" , " doc" });
6967
7068 for (int i = 0 ; i < n; i++) {
71- SEXP ret = PROTECT (Rf_allocVector (VECSXP, 2 ));
69+ cpp11::writable::list ret ({
70+ XPtrNode (nodes->nodeTab [i]),
71+ doc_
72+ });
7273
73- SET_VECTOR_ELT ( ret, 0 , XPtrNode (nodes-> nodeTab [i])) ;
74- SET_VECTOR_ELT ( ret, 1 , doc_) ;
74+ ret. names () = names ;
75+ ret. attr ( " class " ) = " xml_node " ;
7576
76- Rf_setAttrib (ret, R_NamesSymbol, names);
77- Rf_setAttrib (ret, R_ClassSymbol, Rf_mkString (" xml_node" ));
78-
79- SET_VECTOR_ELT (out, i, ret);
80-
81- UNPROTECT (1 );
77+ out[i] = ret;
8278 }
8379
84- UNPROTECT (2 );
8580 return out;
8681 }
87- case XPATH_NUMBER: { return Rf_ScalarReal ( result_->floatval ); }
88- case XPATH_BOOLEAN: { return Rf_ScalarLogical ( result_->boolval ); }
89- case XPATH_STRING: { return Rf_ScalarString ( Rf_mkCharCE (( char *) result_->stringval , CE_UTF8) ); }
82+ case XPATH_NUMBER: { return cpp11::doubles ({ result_->floatval } ); }
83+ case XPATH_BOOLEAN: { return cpp11::logicals ({ result_->boolval } ); }
84+ case XPATH_STRING: { return cpp11::as_sexp (( const char *) result_->stringval ); }
9085 default :
91- Rf_error (" XPath result type: %d not supported" , result_->type );
86+ cpp11::stop (" XPath result type: %d not supported" , result_->type );
9287 }
9388
9489 return R_NilValue;
@@ -105,16 +100,15 @@ class XmlSeeker {
105100};
106101
107102[[cpp11::register ]]
108- cpp11::sexp xpath_search (SEXP node_sxp, SEXP doc_sxp, SEXP xpath_sxp, SEXP nsMap_sxp, SEXP num_results_sxp) {
109-
103+ cpp11::sexp xpath_search (cpp11::sexp node_sxp, cpp11::sexp doc_sxp, cpp11::sexp xpath_sxp, cpp11::strings nsMap_sxp, cpp11::doubles num_results_sxp) {
110104 XPtrNode node (node_sxp);
111105 XPtrDoc doc (doc_sxp);
112106 if (TYPEOF (xpath_sxp) != STRSXP) {
113107 Rf_error (" XPath must be a string, received %s" , Rf_type2char (TYPEOF (xpath_sxp)));
114108 }
115- const char * xpath = CHAR (STRING_ELT (xpath_sxp, 0 ) );
109+ const char * xpath = CHAR (cpp11::strings (xpath_sxp)[ 0 ] );
116110
117- double num_results = REAL ( num_results_sxp) [0 ];
111+ double num_results = num_results_sxp[0 ];
118112
119113 if (num_results == R_PosInf) {
120114 num_results = INT_MAX;
0 commit comments