Annotation of gpl/axl/ns/axl_ns_node.c, revision 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>