1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15 
16 #include <string>
17 #include <string.h>
18 
19 #include "XMLObject.hxx"
20 #include "XMLAttr.hxx"
21 #include "XMLElement.hxx"
22 #include "XMLDocument.hxx"
23 #include "VariableScope.hxx"
24 
25 namespace org_modules_xml
26 {
XMLAttr(const XMLElement & _elem)27 XMLAttr::XMLAttr(const XMLElement & _elem): XMLObject(), elem(_elem)
28 {
29     scilabType = XMLATTRIBUTE;
30     id = scope->getVariableId(*this);
31     scope->registerPointers(elem.getRealNode()->properties, this);
32 }
33 
~XMLAttr()34 XMLAttr::~XMLAttr()
35 {
36     scope->unregisterPointer(elem.getRealNode()->properties);
37     scope->removeId(id);
38 }
39 
getRealXMLPointer() const40 void *XMLAttr::getRealXMLPointer() const
41 {
42     return static_cast < void *>(elem.getRealNode()->properties);
43 }
44 
getXMLObjectParent() const45 const XMLObject *XMLAttr::getXMLObjectParent() const
46 {
47     return &elem;
48 }
49 
getAttributeValue(const char * name) const50 const char *XMLAttr::getAttributeValue(const char *name) const
51 {
52     xmlNode *node = elem.getRealNode();
53     xmlAttr *attrs = xmlHasProp(node, (const xmlChar *)name);
54     if (attrs)
55     {
56         return (const char *)attrs->children->content;
57     }
58 
59     return 0;
60 }
61 
getAttributeValue(const char * ns,const char * name) const62 const char *XMLAttr::getAttributeValue(const char *ns, const char *name) const
63 {
64     xmlNode *node = elem.getRealNode();
65     xmlAttr *attrs = 0;
66     for (xmlAttr * cur = node->properties; cur; cur = cur->next)
67     {
68         if (cur->ns && !strcmp(name, (const char *)cur->name)
69                 && (!strcmp(ns, (const char *)cur->ns->prefix) || !strcmp(ns, (const char *)cur->ns->href)))
70         {
71             attrs = cur;
72             break;
73         }
74     }
75 
76     if (attrs)
77     {
78         return (const char *)attrs->children->content;
79     }
80 
81     return 0;
82 }
83 
getAttributeValue(int index) const84 const char *XMLAttr::getAttributeValue(int index) const
85 {
86     xmlNode *node = elem.getRealNode();
87     int i = 1;
88     for (xmlAttr * cur = node->properties; cur; cur = cur->next, i++)
89     {
90         if (i == index)
91         {
92             return (const char *)cur->children->content;
93         }
94     }
95 
96     return 0;
97 }
98 
setAttributeValue(const char * prefix,const char * name,const char * value) const99 void XMLAttr::setAttributeValue(const char *prefix, const char *name, const char *value) const
100 {
101     setAttributeValue(elem.getRealNode(), prefix, name, value);
102 }
103 
setAttributeValue(xmlNode * node,const char * prefix,const char * name,const char * value)104 void XMLAttr::setAttributeValue(xmlNode * node, const char *prefix, const char *name, const char *value)
105 {
106     if (node && node->type == XML_ELEMENT_NODE)
107     {
108         xmlAttr *attrs = 0;
109 
110         for (xmlAttr * cur = node->properties; cur; cur = cur->next)
111         {
112             if (cur->ns && !strcmp(name, (const char *)cur->name)
113                     && (!strcmp(prefix, (const char *)cur->ns->prefix) || !strcmp(prefix, (const char *)cur->ns->href)))
114             {
115                 attrs = cur;
116                 break;
117             }
118         }
119 
120         if (attrs)
121         {
122             xmlSetNsProp(node, attrs->ns, (const xmlChar *)name, (const xmlChar *)value);
123         }
124         else
125         {
126             xmlNs *ns = 0;
127 
128             if (!strncmp(prefix, "http://", strlen("http://")))
129             {
130                 ns = xmlSearchNsByHref(node->doc, node, (const xmlChar *)prefix);
131             }
132             else
133             {
134                 ns = xmlSearchNs(node->doc, node, (const xmlChar *)prefix);
135             }
136 
137             if (ns)
138             {
139                 xmlSetNsProp(node, ns, (const xmlChar *)name, (const xmlChar *)value);
140             }
141             else
142             {
143                 xmlSetProp(node, (const xmlChar *)name, (const xmlChar *)value);
144             }
145         }
146     }
147 }
148 
setAttributeValue(xmlNode * node,const char ** prefix,const char ** name,const char ** value,int size)149 void XMLAttr::setAttributeValue(xmlNode * node, const char **prefix, const char **name, const char **value, int size)
150 {
151     if (node && node->type == XML_ELEMENT_NODE)
152     {
153         for (int i = 0; i < size; i++)
154         {
155             setAttributeValue(node, prefix[i], name[i], value[i]);
156         }
157     }
158 }
159 
setAttributeValue(const char ** prefix,const char ** name,const char ** value,int size) const160 void XMLAttr::setAttributeValue(const char **prefix, const char **name, const char **value, int size) const
161 {
162     for (int i = 0; i < size; i++)
163     {
164         setAttributeValue(prefix[i], name[i], value[i]);
165     }
166 }
167 
setAttributeValue(int index,const char * value) const168 void XMLAttr::setAttributeValue(int index, const char *value) const
169 {
170     setAttributeValue(elem.getRealNode(), index, value);
171 }
172 
setAttributeValue(xmlNode * node,int index,const char * value)173 void XMLAttr::setAttributeValue(xmlNode * node, int index, const char *value)
174 {
175     if (node && node->type == XML_ELEMENT_NODE)
176     {
177         int i = 1;
178 
179         for (xmlAttr * cur = node->properties; cur; cur = cur->next, i++)
180         {
181             if (i == index)
182             {
183                 cur->children->content = xmlStrdup((const xmlChar *)value);
184             }
185         }
186     }
187 }
188 
setAttributeValue(const char * name,const char * value) const189 void XMLAttr::setAttributeValue(const char *name, const char *value) const
190 {
191     setAttributeValue(elem.getRealNode(), name, value);
192 }
193 
setAttributeValue(xmlNode * node,const char * name,const char * value)194 void XMLAttr::setAttributeValue(xmlNode * node, const char *name, const char *value)
195 {
196     if (node && node->type == XML_ELEMENT_NODE)
197     {
198         xmlAttr *attrs = xmlHasProp(node, (const xmlChar *)name);
199 
200         if (attrs)
201         {
202             xmlSetProp(node, (const xmlChar *)name, (const xmlChar *)value);
203         }
204         else
205         {
206             xmlNewProp(node, (const xmlChar *)name, (const xmlChar *)value);
207         }
208     }
209 }
210 
setAttributeValue(xmlNode * node,const char ** name,const char ** value,int size)211 void XMLAttr::setAttributeValue(xmlNode * node, const char **name, const char **value, int size)
212 {
213     if (node && node->type == XML_ELEMENT_NODE)
214     {
215         for (int i = 0; i < size; i++)
216         {
217             setAttributeValue(node, name[i], value[i]);
218         }
219     }
220 }
221 
setAttributeValue(const char ** name,const char ** value,int size) const222 void XMLAttr::setAttributeValue(const char **name, const char **value, int size) const
223 {
224     for (int i = 0; i < size; i++)
225     {
226         setAttributeValue(name[i], value[i]);
227     }
228 }
229 
getSize() const230 int XMLAttr::getSize() const
231 {
232     return getSize(elem.getRealNode()->properties);
233 }
234 
getSize(xmlAttr * attr)235 int XMLAttr::getSize(xmlAttr * attr)
236 {
237     int i = 0;
238     for (xmlAttr * cur = attr; cur; cur = cur->next, i++)
239     {
240         ;
241     }
242 
243     return i;
244 }
245 
toString() const246 const std::string XMLAttr::toString() const
247 {
248     std::ostringstream oss;
249     xmlNode *node = elem.getRealNode();
250 
251     oss << "XML Attributes" << std::endl;
252     for (xmlAttr * cur = node->properties; cur; cur = cur->next)
253     {
254         if (cur->ns)
255         {
256             oss << cur->ns->prefix << ":" << cur->name << " --> " << cur->children->content << std::endl;
257         }
258         else
259         {
260             oss << cur->name << " --> " << cur->children->content << std::endl;
261         }
262     }
263 
264     return oss.str();
265 }
266 
getNames() const267 const char ** XMLAttr::getNames() const
268 {
269     int size = getSize();
270     int i = 0;
271     char ** arr = new char*[size + 1];
272     xmlNode * node = elem.getRealNode();
273 
274     for (xmlAttr * cur = node->properties; cur; cur = cur->next, i++)
275     {
276         arr[i] = (char *)cur->name;
277     }
278     arr[size] = 0;
279 
280     return const_cast<const char**>(arr);
281 }
282 }
283