1 /*
2  *  TurboXSL XML+XSLT processing library
3  *  XMLNODE operations
4  *
5  *
6  *  (c) Egor Voznessenski, voznyak@mail.ru
7  *
8  *  $Id$
9  *
10 **/
11 
12 #include <stdio.h>
13 
14 #include "ltr_xsl.h"
15 #include "xsl_elements.h"
16 
xml_unlink_node(XMLNODE * node)17 void xml_unlink_node(XMLNODE *node)
18 {
19   if(node->prev) {
20     node->prev->next = node->next;
21   } else {
22     if(node->parent)
23       node->parent->children = node->next;
24   }
25   if(node->next) {
26     node->next->prev = node->prev;
27   }
28 }
29 
30 /*********** for static-allocated nodes *******************/
31 
xml_new_node(TRANSFORM_CONTEXT * pctx,XMLSTRING name,NODETYPE type)32 XMLNODE *xml_new_node(TRANSFORM_CONTEXT *pctx, XMLSTRING name, NODETYPE type)
33 {
34     XMLNODE *ret = memory_allocator_new(sizeof(XMLNODE));
35     ret->type = type;
36     ret->name = name;
37     ret->uid = ret;
38     return ret;
39 }
40 
xml_append_child(TRANSFORM_CONTEXT * pctx,XMLNODE * node,NODETYPE type)41 XMLNODE *xml_append_child(TRANSFORM_CONTEXT *pctx, XMLNODE *node, NODETYPE type)
42 {
43   XMLNODE *ret = xml_new_node(pctx, NULL, type);
44   xml_add_child(node, ret);
45   return ret;
46 }
47 
xml_add_child(XMLNODE * node,XMLNODE * child)48 void xml_add_child(XMLNODE *node, XMLNODE *child)
49 {
50     if (!child)
51     {
52         error("xml_add_child:: child is NULL");
53         return;
54     }
55 
56     if (node->children)
57     {
58         XMLNODE *prev;
59         for (prev = node->children; prev->next; prev = prev->next);
60         child->prev = prev;
61         prev->next = child;
62     }
63     else
64     {
65         node->children = child;
66     }
67     child->parent = node;
68 }
69 
xpath_nodeset_copy(TRANSFORM_CONTEXT * pctx,XMLNODE * src)70 XMLNODE *xpath_nodeset_copy(TRANSFORM_CONTEXT *pctx, XMLNODE *src)
71 {
72   unsigned i = 0;
73   XMLNODE *dst,*ret;
74   if(!src)
75     return NULL;  //empty nodeset
76 
77   ret = dst = xml_new_node(pctx, NULL,src->type);
78   for(;;) {
79     dst->original = src->original;
80     dst->name = src->name;
81     dst->position = ++i;
82     dst->order = src->order;
83     dst->children = src->children;
84     dst->attributes = src->attributes;
85     dst->content = src->content;
86     dst->parent = src->parent;
87     if(src->next) {
88       src = src->next;
89       dst->next = xml_new_node(pctx, NULL,src->type);
90       dst->next->prev = dst;
91       dst=dst->next;
92     } else {
93       break;
94     }
95   }
96   return ret;
97 }
98 
is_node_parallel(XMLNODE * node)99 int is_node_parallel(XMLNODE *node)
100 {
101     if (node->type == TEXT_NODE) return 0;
102 
103     XMLNODE *t = node->next;
104     while (t != NULL)
105     {
106         if (t->type == ELEMENT_NODE) return 1;
107         t = t->next;
108     }
109 
110     return 0;
111 }
112 
XMLCreateDocument()113 XMLNODE *XMLCreateDocument()
114 {
115   memory_allocator *allocator = memory_allocator_create();
116   memory_allocator_add_entry(allocator, pthread_self(), 100000);
117   memory_allocator_set_current(allocator);
118 
119   XMLNODE *result = xml_new_node(NULL, xsl_s_root, EMPTY_NODE);
120   result->allocator = allocator;
121 
122   return result;
123 }
124 
XMLCreateElement(XMLNODE * parent,char * name)125 XMLNODE *XMLCreateElement(XMLNODE *parent, char *name)
126 {
127   XMLNODE *result = xml_new_node(NULL, xmls_new_string_literal(name), ELEMENT_NODE);
128   if (parent != NULL) xml_add_child(parent, result);
129   return result;
130 }
131 
XMLAddText(XMLNODE * element,char * text)132 void XMLAddText(XMLNODE *element, char *text)
133 {
134   XMLNODE *result = xml_new_node(NULL, NULL, TEXT_NODE);
135   result->content = xmls_new_string_literal(text);
136   result->parent = element;
137   xml_add_child(element, result);
138 }
139 
XMLAddAttribute(XMLNODE * element,char * name,char * value)140 void XMLAddAttribute(XMLNODE *element, char *name, char *value)
141 {
142   XMLNODE *attribute = xml_new_node(NULL, xmls_new_string_literal(name), ATTRIBUTE_NODE);
143   attribute->content = xmls_new_string_literal(value);
144   attribute->parent = element;
145 
146   attribute->next = element->attributes;
147   element->attributes = attribute;
148 }
149 
XMLAddChildFromString(XSLTGLOBALDATA * context,XMLNODE * element,char * value)150 void XMLAddChildFromString(XSLTGLOBALDATA *context, XMLNODE *element, char *value)
151 {
152   if (value == NULL || strlen(value) == 0) return;
153 
154   XMLNODE *root = xml_parse_string(context, value, 1);
155   if (root == NULL)
156   {
157     error("XMLAddChildFromString:: fail to parse string: %s", value);
158     return;
159   }
160   xml_add_child(element, root->children);
161 }
162