/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/src/mxml-2.2.2/mxml-search.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 207 $ : Last Committed Revision
00003  * $Date: 2008-07-11 17:55:19 -0700 (Fri, 11 Jul 2008) $ : Last Committed Date */
00004 /*
00005  * "$Id: mxml-search.c,v 1.1 2007/05/23 20:43:27 david_ko Exp $"
00006  *
00007  * Search/navigation functions for Mini-XML, a small XML-like file
00008  * parsing library.
00009  *
00010  * Copyright 2003-2005 by Michael Sweet.
00011  *
00012  * This program is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Library General Public
00014  * License as published by the Free Software Foundation; either
00015  * version 2, or (at your option) any later version.
00016  *
00017  * This program is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU General Public License for more details.
00021  *
00022  * Contents:
00023  *
00024  *   mxmlFindElement() - Find the named element.
00025  *   mxmlWalkNext()    - Walk to the next logical node in the tree.
00026  *   mxmlWalkPrev()    - Walk to the previous logical node in the tree.
00027  */
00028 
00029 /*
00030  * Include necessary headers...
00031  */
00032 
00033 #include "config.h"
00034 #include "mxml.h"
00035 
00036 
00037 /*
00038  * 'mxmlFindElement()' - Find the named element.
00039  *
00040  * The search is constrained by the name, attribute name, and value; any
00041  * NULL names or values are treated as wildcards, so different kinds of
00042  * searches can be implemented by looking for all elements of a given name
00043  * or all elements with a specific attribute. The descend argument determines
00044  * whether the search descends into child nodes; normally you will use
00045  * MXML_DESCEND_FIRST for the initial search and MXML_NO_DESCEND to find
00046  * additional direct descendents of the node. The top node argument
00047  * constrains the search to a particular node's children.
00048  */
00049 
00050 mxml_node_t *                           /* O - Element node or NULL */
00051 mxmlFindElement(mxml_node_t *node,      /* I - Current node */
00052                 mxml_node_t *top,       /* I - Top node */
00053                 const char  *name,      /* I - Element name or NULL for any */
00054                 const char  *attr,      /* I - Attribute name, or NULL for none */
00055                 const char  *value,     /* I - Attribute value, or NULL for any */
00056                 int         descend)    /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */
00057 {
00058   const char    *temp;                  /* Current attribute value */
00059 
00060 
00061  /*
00062   * Range check input...
00063   */
00064 
00065   if (!node || !top || (!attr && value))
00066     return (NULL);
00067 
00068  /*
00069   * Start with the next node...
00070   */
00071 
00072   node = mxmlWalkNext(node, top, descend);
00073 
00074  /*
00075   * Loop until we find a matching element...
00076   */
00077 
00078   while (node != NULL)
00079   {
00080    /*
00081     * See if this node matches...
00082     */
00083 
00084     if (node->type == MXML_ELEMENT &&
00085         node->value.element.name &&
00086         (!name || !strcmp(node->value.element.name, name)))
00087     {
00088      /*
00089       * See if we need to check for an attribute...
00090       */
00091 
00092       if (!attr)
00093         return (node);                  /* No attribute search, return it... */
00094 
00095      /*
00096       * Check for the attribute...
00097       */
00098 
00099       if ((temp = mxmlElementGetAttr(node, attr)) != NULL)
00100       {
00101        /*
00102         * OK, we have the attribute, does it match?
00103         */
00104 
00105         if (!value || !strcmp(value, temp))
00106           return (node);                /* Yes, return it... */
00107       }
00108     }
00109 
00110    /*
00111     * No match, move on to the next node...
00112     */
00113 
00114     if (descend == MXML_DESCEND)
00115       node = mxmlWalkNext(node, top, MXML_DESCEND);
00116     else
00117       node = node->next;
00118   }
00119 
00120   return (NULL);
00121 }
00122 
00123 
00124 /*
00125  * 'mxmlWalkNext()' - Walk to the next logical node in the tree.
00126  *
00127  * The descend argument controls whether the first child is considered
00128  * to be the next node. The top node argument constrains the walk to
00129  * the node's children.
00130  */
00131 
00132 mxml_node_t *                           /* O - Next node or NULL */
00133 mxmlWalkNext(mxml_node_t *node,         /* I - Current node */
00134              mxml_node_t *top,          /* I - Top node */
00135              int         descend)       /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */
00136 {
00137   if (!node)
00138     return (NULL);
00139   else if (node->child && descend)
00140     return (node->child);
00141   else if (node->next)
00142     return (node->next);
00143   else if (node->parent && node->parent != top)
00144   {
00145     node = node->parent;
00146 
00147     while (!node->next)
00148       if (node->parent == top || !node->parent)
00149         return (NULL);
00150       else
00151         node = node->parent;
00152 
00153     return (node->next);
00154   }
00155   else
00156     return (NULL);
00157 }
00158 
00159 
00160 /*
00161  * 'mxmlWalkPrev()' - Walk to the previous logical node in the tree.
00162  *
00163  * The descend argument controls whether the previous node's last child
00164  * is considered to be the previous node. The top node argument constrains
00165  * the walk to the node's children.
00166  */
00167 
00168 mxml_node_t *                           /* O - Previous node or NULL */
00169 mxmlWalkPrev(mxml_node_t *node,         /* I - Current node */
00170              mxml_node_t *top,          /* I - Top node */
00171              int         descend)       /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */
00172 {
00173   if (!node)
00174     return (NULL);
00175   else if (node->prev)
00176   {
00177     if (node->prev->last_child && descend)
00178     {
00179      /*
00180       * Find the last child under the previous node...
00181       */
00182 
00183       node = node->prev->last_child;
00184 
00185       while (node->last_child)
00186         node = node->last_child;
00187 
00188       return (node);
00189     }
00190     else
00191       return (node->prev);
00192   }
00193   else if (node->parent != top)
00194     return (node->parent);
00195   else
00196     return (NULL);
00197 }
00198 
00199 
00200 /*
00201  * End of "$Id: mxml-search.c,v 1.1 2007/05/23 20:43:27 david_ko Exp $".
00202  */

Generated on Fri Jul 11 17:59:45 2008 for Mobile-C by  doxygen 1.5.4