/home/dko/projects/mobilec/trunk/src/mxml-2.2.2/mxml-search.c

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

Generated on Fri May 16 14:49:54 2008 for Mobile-C by  doxygen 1.5.4