Annotation of gpl/axl/ns/axl_ns_node.c, revision 1.1.1.1
1.1 misho 1: /*
2: * LibAxl: Another XML library
3: * Copyright (C) 2006 Advanced Software Production Line, S.L.
4: *
5: * This program is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public License
7: * as published by the Free Software Foundation; either version 2.1 of
8: * the License, or (at your option) any later version.
9: *
10: * This program is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: * GNU Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this program; if not, write to the Free
17: * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18: * 02111-1307 USA
19: *
20: * You may find a copy of the license under this software is released
21: * at COPYING file. This is LGPL software: you are welcome to
22: * develop proprietary applications using this library without any
23: * royalty or fee but returning back any change, improvement or
24: * addition in the form of source code, project image, documentation
25: * patches, etc.
26: *
27: * For commercial support on build XML enabled solutions contact us:
28: *
29: * Postal address:
30: * Advanced Software Production Line, S.L.
31: * Edificio Alius A, Oficina 102,
32: * C/ Antonio Suarez Nº 10,
33: * Alcalá de Henares 28802 Madrid
34: * Spain
35: *
36: * Email address:
37: * info@aspl.es - http://www.aspl.es/xml
38: */
39: #include <axl_ns.h>
40:
41: #define LOG_DOMAIN "axl-ns-node"
42:
43: /**
44: * \defgroup axl_ns_node_module Axl Node Namespace: Xml 1.0 namespace support for XML nodes
45: */
46:
47: /**
48: * \addtogroup axl_ns_node_module
49: * @{
50: */
51:
52: /**
53: * @brief Allows to perform a node name (tag) checking using XML 1.0
54: * Namespace rules.
55: *
56: * This function must be used instead of \ref NODE_CMP_NAME if your application must support
57: * XML 1.0 namespaces.
58: *
59: * The idea is that you declares the namespace that you will recognize
60: * using a macro definition at some place in your headers, as follows:
61: * \code
62: * #define YOUR_NS "http://yourdomain.com/somepath/yourapplication"
63: * \endcode
64: *
65: * Previous namespace must be unique. This is crucial to avoid tag
66: * clashing. Now, you use this namespace identifier and the local name
67: * of your tag to check a particular node to have a particular name as
68: * follows:
69: *
70: * \code
71: * if (axl_ns_node_cmp (node, YOUR_NS, "table")) {
72: * // found table node inside your namespace
73: * }
74: * \endcode
75: *
76: * It is required to call first to \ref axl_ns_doc_validate in order
77: * to make this function to properly work.
78: *
79: * @param node The node that will be checked.
80: *
81: * @param ns The namespace to use to match the node name.
82: *
83: * @param name The node name to be checked (without namespace
84: * prefixes).
85: *
86: * @return \ref axl_true if the node name is the one expected, binded by
87: * the namespace declaration, otherwise \ref axl_false is returned. The
88: * function returns \ref axl_false in the of some paremeter is provided
89: * null.
90: */
91: axl_bool axl_ns_node_cmp (axlNode * node,
92: const char * ns,
93: const char * name)
94: {
95: int position;
96: char * _name;
97:
98: axl_return_val_if_fail (node, axl_false);
99: axl_return_val_if_fail (ns, axl_false);
100: axl_return_val_if_fail (name, axl_false);
101:
102: /* check the name is namespace prefixed */
103: if (axl_ns_node_is_prefixed (node, &position)) {
104:
105: /* namespace bound */
106: _name = (char*) axl_node_get_name (node);
107: _name[position] = 0;
108:
109: /* call to check */
110: if (! axl_ns_doc_node_check (node, _name, ns)) {
111: /* restore the value */
112: _name[position] = ':';
113: return axl_false;
114: }
115:
116: /* restore the value */
117: _name[position] = ':';
118:
119: /* now check the node name (now we know the namespace is checked) */
120: return axl_cmp (name, _name + position + 1);
121: } /* end if */
122:
123: /* look for the default namespace */
124: if (! axl_ns_doc_check_default (node, ns)) {
125: /* default namespace for the current node doesn't match */
126: return axl_false;
127: }
128:
129: /* default namespace match, check the node name */
130: return axl_cmp (name, axl_node_get_name (node));
131: }
132:
133: /**
134: * @brief Allows to find the first child called as provided inside the
135: * childs (including its descendants) hold by the parent provided,
136: * with namespace support.
137: *
138: * This function must be used instead of \ref
139: * axl_node_find_called if your application must support
140: * XML 1.0 namespaces.
141: *
142: * This function is similar to \ref axl_ns_node_get_child_called but
143: * it will look for a child node called as provided not only in direct
144: * childs hold by the parent but also on its all descendants, giving
145: * support to configure the namespace where the lookup will be run.
146: *
147: * If you are looking for a function to search for a particular child
148: * node inside direct childs stored for the provided parent, then you
149: * must use \ref axl_ns_node_get_child_called.
150: *
151: * There is also a convenience function that allows to perform a
152: * lookup using as a reference a document (using the root node from
153: * it): \ref axl_ns_doc_find_called.
154: *
155: * @param parent The parent where the lookup will be produced.
156: *
157: * @param ns The namespace where the node will be searched
158: *
159: * @param name The name of the child to be looked up.
160: *
161: * @return A reference to the node found (first instaned matching the
162: * name) or NULL if it fails to find a child.
163: */
164: axlNode * axl_ns_node_find_called (axlNode * parent,
165: const char * ns,
166: const char * name)
167: {
168: axlNode * node;
169: axlNode * child;
170:
171: /* for the first child found */
172: node = axl_ns_node_get_child_called (parent, ns, name);
173: if (node != NULL)
174: return node;
175:
176: /* now, for all childs, try to look for the node */
177: node = axl_node_get_first_child (parent);
178: while (node != NULL) {
179: /* make the search */
180: child = axl_ns_node_find_called (node, ns, name);
181:
182: /* child found, return the reference */
183: if (child != NULL)
184: return child;
185:
186: /* get next */
187: node = axl_node_get_next (node);
188: } /* end while */
189:
190: /* child note found */
191: return NULL;
192: }
193:
194: /**
195: * @brief Allows to get a particular child node for the given node
196: * (\ref axlNode), inside the provided namespace.
197: *
198: * This function must be used instead of \ref
199: * axl_node_get_child_called if your application must support
200: * XML 1.0 namespaces.
201: *
202: * @param parent The parent node where the child will be looked up.
203: *
204: * @param ns The namespace where the lookup will be run.
205: *
206: * @param name The name for the child to search.
207: *
208: * @return A refernce to a \ref axlNode or NULL if no child exists
209: * called by the name provided, inside the node provided.
210: */
211: axlNode * axl_ns_node_get_child_called (axlNode * parent,
212: const char * ns,
213: const char * name)
214: {
215: axlNode * node;
216:
217: /* for the first child found */
218: node = axl_node_get_first_child (parent);
219: while (node != NULL) {
220: /* check and return the node found */
221: if (axl_ns_node_cmp (node, ns, name))
222: return node;
223:
224: /* get next */
225: node = axl_node_get_next (node);
226: } /* end while */
227:
228: return NULL;
229: }
230:
231: /**
232: * @brief Allows to get the next node, following to the node provided,
233: * matching the given name, inside the namespace configuration
234: * provided.
235: *
236: * This function must be used instead of \ref
237: * axl_node_get_next_called if your application must support
238: * XML 1.0 namespaces.
239: *
240: * @param node The node that is requested to return its next sibling
241: * node.
242: *
243: * @param ns The namespace value to use to perform the search.
244: *
245: * @param name The name to match for the next node.
246: *
247: * @return A reference to the next node or NULL if it fails. The
248: * returned reference mustn't be deallocated.
249: */
250: axlNode * axl_ns_node_get_next_called (axlNode * node,
251: const char * ns,
252: const char * name)
253: {
254: axlNode * next;
255:
256: axl_return_val_if_fail (node, NULL);
257: axl_return_val_if_fail (ns, NULL);
258: axl_return_val_if_fail (name, NULL);
259:
260: /* while there is a next node */
261: next = axl_node_get_next (node);
262: while (next != NULL) {
263: /* check the node */
264: if (axl_ns_node_cmp (next, ns, name))
265: return next;
266:
267: /* update to the next */
268: next = axl_node_get_next (next);
269: } /* end while */
270:
271: /* no node was found */
272: return NULL;
273: }
274:
275: /**
276: * @brief Allows to get the previous node, preceding to the node
277: * provided, matching the given name, inside the given namespace
278: * value.
279: *
280: * @param node The node that is requested to return its previous
281: * sibling node.
282: *
283: * @param ns The namespace to be used to perform the lookup.
284: *
285: * @param name The name to match for the previous node.
286: *
287: * @return A reference to the previous node or NULL if it fails. The
288: * returned reference mustn't be deallocated.
289: */
290: axlNode * axl_ns_node_get_previous_called (axlNode * node,
291: const char * ns,
292: const char * name)
293: {
294: axlNode * previous;
295:
296: axl_return_val_if_fail (node, NULL);
297: axl_return_val_if_fail (ns, NULL);
298: axl_return_val_if_fail (name, NULL);
299:
300: /* while there is a previous node */
301: previous = axl_node_get_previous (node);
302: while (previous != NULL) {
303: /* check the node */
304: if (axl_ns_node_cmp (previous, ns, name))
305: return previous;
306:
307: /* update to the next */
308: previous = axl_node_get_previous (previous);
309: } /* end while */
310:
311: /* no node was found */
312: return NULL;
313: }
314:
315: /**
316: * @brief Allows to check if the provided node, has a name (tag) which is namespace prefixed.
317: *
318: * The following name is considered namespace prefixed
319: * <b>edi:price</b> while using <b>edi</b> is not.
320: *
321: * @param node The node to be checked to have a name prefixed.
322: *
323: * @param position Optional variable where the position of the ":"
324: * inside the xml node name is returned. On \ref axl_false, the value is
325: * configured to -1.
326: *
327: * @return \ref axl_true if the node is prefixed, otherwise \ref axl_false is
328: * returned. The function also returns \ref axl_false if the node
329: * reference received is NULL.
330: */
331: axl_bool axl_ns_node_is_prefixed (axlNode * node, int * position)
332: {
333: int iterator = 0;
334: const char * name;
335:
336: axl_return_val_if_fail (node, axl_false);
337:
338: /* configure default position */
339: if (position)
340: *position = -1;
341:
342: /* get the node name and check each character */
343: name = axl_node_get_name (node);
344: while (name[iterator] != 0) {
345:
346: /* if found, notify this */
347: if (name[iterator] == ':') {
348: /* configure default position */
349: if (position)
350: *position = iterator;
351:
352: return axl_true;
353: } /* end if */
354:
355: /* go to the next character */
356: iterator++;
357: } /* end while */
358:
359: /* reached this point, axl_false must be returned */
360: return axl_false;
361: }
362:
363: /**
364: * @}
365: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>