https://github.com/cran/XML
Tip revision: 619c5628a5668dd44f5251a01ea6857c37aa6677 authored by ORPHANED on 08 February 2019, 08:25:32 UTC
version 3.98-1.17
version 3.98-1.17
Tip revision: 619c562
fixNS.c
#include <libxml/tree.h>
#include "RSCommon.h"
#include "RS_XML.h"
#define R_USE_XML_ENCODING 1
#include "Utils.h" /* R_createXMLNodeRef, Encoding macros. */
// need to release any <dummy> namespace.
int fixDummyNS(xmlNodePtr node, int recursive);
int setDummyNS(xmlNodePtr node, const xmlChar *prefix);
xmlNs *findNSByPrefix(xmlNodePtr node, const xmlChar *prefix);
SEXP
R_fixDummyNS(SEXP r_node, SEXP r_recursive)
{
xmlNodePtr node;
int status;
node = (xmlNodePtr) R_ExternalPtrAddr(r_node);
status = fixDummyNS(node, LOGICAL(r_recursive)[0]);
return(ScalarInteger(status));
}
int
fixDummyNS(xmlNodePtr node, int recursive)
{
xmlNs *ns = node->ns;
int count = 0;
if(ns && strcmp((const char *)ns->href, "<dummy>") == 0)
count = setDummyNS(node, ns->prefix);
if(recursive) {
xmlNodePtr ptr = node->children;
while(ptr) {
count += fixDummyNS(ptr, recursive);
ptr = ptr->next;
}
}
return(count);
}
int
setDummyNS(xmlNodePtr node, const xmlChar *prefix)
{
xmlNodePtr a = node->parent;
while(a) {
xmlNs *ns;
ns = findNSByPrefix(a, prefix);
if(ns) {
#ifdef R_XML_DEBUG
fprintf(stderr, "mapping %s to %s\n", prefix, ns->href);fflush(stderr);
#endif
node->nsDef = node->nsDef->next;
xmlSetNs(node, ns);
return(1);
}
a = a->parent;
}
return(0);
}
xmlNs *
findNSByPrefix(xmlNodePtr node, const xmlChar *prefix)
{
xmlNs *ptr = node->nsDef;
while(ptr) {
if((!prefix || !prefix[0]) && !ptr->prefix)
return(ptr);
if(prefix && ptr->prefix && strcmp((const char *)ptr->prefix, (const char *)prefix) == 0)
return(ptr);
ptr = ptr->next;
}
return(NULL);
}
void
setDefaultNs(xmlNodePtr node, xmlNsPtr ns, int recursive)
{
if(!node->ns)
xmlSetNs(node, ns);
if(recursive) {
xmlNodePtr cur = node->children;
while(cur) {
setDefaultNs(cur, ns, 1);
cur = cur->next;
}
}
}
SEXP
R_getAncestorDefaultNSDef(SEXP r_node, SEXP r_recursive)
{
xmlNodePtr cur, node;
xmlNs *ans = NULL;
cur = (xmlNodePtr) R_ExternalPtrAddr(r_node);
node = cur->parent;
while(node && (node->type != XML_DOCUMENT_NODE &&
node->type != XML_HTML_DOCUMENT_NODE)) { /* Need to check for HTML_DOC or XML_DOC ?*/
ans = findNSByPrefix(node, NULL);
if(ans)
break;
node = node->parent;
}
if(ans) {
xmlSetNs(cur, ans);
if(LOGICAL(r_recursive)[0]) {
setDefaultNs(cur, ans, 1);
}
return(ScalarLogical(1)); // R_createXMLNsRef(ans));
}
return(R_NilValue);
}