File: fixNS.c

package info (click to toggle)
r-cran-xml 3.99-0.18-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 3,688 kB
  • sloc: ansic: 6,656; xml: 2,890; asm: 486; sh: 12; makefile: 2
file content (126 lines) | stat: -rw-r--r-- 2,565 bytes parent folder | download | duplicates (5)
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);
}