1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
#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);
}
|