Changeset 2727


Ignore:
Timestamp:
Jun 1, 2009 9:28:28 AM (15 years ago)
Author:
bennylp
Message:

Ticket #868: Added functions to search XML child nodes recursively

Location:
pjproject/trunk/pjlib-util
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/include/pjlib-util/xml.h

    r2394 r2727  
    150150 
    151151/** 
    152  * Find first node with the specified name. 
     152 * Find first direct child node with the specified name. 
    153153 * 
    154154 * @param parent    Parent node. 
     
    157157 * @return          XML node found or NULL. 
    158158 */ 
    159 PJ_DECL(pj_xml_node*) pj_xml_find_node(pj_xml_node *parent, const pj_str_t *name); 
    160  
    161 /** 
    162  * Find first node with the specified name. 
     159PJ_DECL(pj_xml_node*) pj_xml_find_node(const pj_xml_node *parent,  
     160                                       const pj_str_t *name); 
     161 
     162/** 
     163 * Find next direct child node with the specified name. 
    163164 * 
    164165 * @param parent    Parent node. 
     
    168169 * @return          XML node found or NULL. 
    169170 */ 
    170 PJ_DECL(pj_xml_node*) pj_xml_find_next_node(pj_xml_node *parent, pj_xml_node *node, 
     171PJ_DECL(pj_xml_node*) pj_xml_find_next_node(const pj_xml_node *parent,  
     172                                            const pj_xml_node *node, 
    171173                                            const pj_str_t *name); 
    172174 
    173175/** 
    174  * Find first attribute within a node with the specified name and optional value. 
     176 * Recursively find the first node with the specified name in the child nodes 
     177 * and their children. 
     178 * 
     179 * @param parent    Parent node. 
     180 * @param name      Node name to find. 
     181 * 
     182 * @return          XML node found or NULL. 
     183 */ 
     184PJ_DECL(pj_xml_node*) pj_xml_find_node_rec(const pj_xml_node *parent,  
     185                                           const pj_str_t *name); 
     186 
     187 
     188/** 
     189 * Find first attribute within a node with the specified name and optional  
     190 * value. 
    175191 * 
    176192 * @param node      XML Node. 
     
    180196 * @return          XML attribute found, or NULL. 
    181197 */ 
    182 PJ_DECL(pj_xml_attr*) pj_xml_find_attr(pj_xml_node *node, const pj_str_t *name, 
     198PJ_DECL(pj_xml_attr*) pj_xml_find_attr(const pj_xml_node *node,  
     199                                       const pj_str_t *name, 
    183200                                       const pj_str_t *value); 
    184201 
     
    188205 * 
    189206 * @param parent    Parent node. 
    190  * @param name      Optional name. 
     207 * @param name      Optional name. If this is NULL, the name will not be 
     208 *                  matched. 
    191209 * @param data      Data to be passed to matching function. 
    192210 * @param match     Optional matching function. 
     
    194212 * @return          The first matched node, or NULL. 
    195213 */ 
    196 PJ_DECL(pj_xml_node*) pj_xml_find( pj_xml_node *parent, const pj_str_t *name, 
     214PJ_DECL(pj_xml_node*) pj_xml_find( const pj_xml_node *parent,  
     215                                   const pj_str_t *name, 
    197216                                   const void *data,  
    198                                    pj_bool_t (*match)(pj_xml_node *, const void*)); 
     217                                   pj_bool_t (*match)(const pj_xml_node *,  
     218                                                      const void*)); 
     219 
     220 
     221/** 
     222 * Recursively find a child node with the specified name and match the  
     223 * function. 
     224 * 
     225 * @param parent    Parent node. 
     226 * @param name      Optional name. If this is NULL, the name will not be 
     227 *                  matched. 
     228 * @param data      Data to be passed to matching function. 
     229 * @param match     Optional matching function. 
     230 * 
     231 * @return          The first matched node, or NULL. 
     232 */ 
     233PJ_DECL(pj_xml_node*) pj_xml_find_rec(const pj_xml_node *parent,  
     234                                      const pj_str_t *name, 
     235                                      const void *data,  
     236                                      pj_bool_t (*match)(const pj_xml_node*,  
     237                                                         const void*)); 
    199238 
    200239 
  • pjproject/trunk/pjlib-util/src/pjlib-util/xml.c

    r2394 r2727  
    341341} 
    342342 
    343 PJ_DEF(pj_xml_node*) pj_xml_find_node(pj_xml_node *parent, const pj_str_t *name) 
    344 { 
    345     pj_xml_node *node = parent->node_head.next; 
     343PJ_DEF(pj_xml_node*) pj_xml_find_node(const pj_xml_node *parent,  
     344                                      const pj_str_t *name) 
     345{ 
     346    const pj_xml_node *node = parent->node_head.next; 
    346347 
    347348    PJ_CHECK_STACK(); 
     
    349350    while (node != (void*)&parent->node_head) { 
    350351        if (pj_stricmp(&node->name, name) == 0) 
    351             return node; 
     352            return (pj_xml_node*)node; 
    352353        node = node->next; 
    353354    } 
     
    355356} 
    356357 
    357  
    358 PJ_DEF(pj_xml_node*) pj_xml_find_next_node( pj_xml_node *parent, pj_xml_node *node, 
     358PJ_DEF(pj_xml_node*) pj_xml_find_node_rec(const pj_xml_node *parent,  
     359                                          const pj_str_t *name) 
     360{ 
     361    const pj_xml_node *node = parent->node_head.next; 
     362 
     363    PJ_CHECK_STACK(); 
     364 
     365    while (node != (void*)&parent->node_head) { 
     366        pj_xml_node *found; 
     367        if (pj_stricmp(&node->name, name) == 0) 
     368            return (pj_xml_node*)node; 
     369        found = pj_xml_find_node_rec(node, name); 
     370        if (found) 
     371            return (pj_xml_node*)found; 
     372        node = node->next; 
     373    } 
     374    return NULL; 
     375} 
     376 
     377PJ_DEF(pj_xml_node*) pj_xml_find_next_node( const pj_xml_node *parent,  
     378                                            const pj_xml_node *node, 
    359379                                            const pj_str_t *name) 
    360380{ 
     
    364384    while (node != (void*)&parent->node_head) { 
    365385        if (pj_stricmp(&node->name, name) == 0) 
    366             return node; 
     386            return (pj_xml_node*)node; 
    367387        node = node->next; 
    368388    } 
     
    371391 
    372392 
    373 PJ_DEF(pj_xml_attr*) pj_xml_find_attr( pj_xml_node *node, const pj_str_t *name, 
     393PJ_DEF(pj_xml_attr*) pj_xml_find_attr( const pj_xml_node *node,  
     394                                       const pj_str_t *name, 
    374395                                       const pj_str_t *value) 
    375396{ 
    376     pj_xml_attr *attr = node->attr_head.next; 
     397    const pj_xml_attr *attr = node->attr_head.next; 
    377398    while (attr != (void*)&node->attr_head) { 
    378399        if (pj_stricmp(&attr->name, name)==0) { 
    379400            if (value) { 
    380401                if (pj_stricmp(&attr->value, value)==0) 
    381                     return attr; 
     402                    return (pj_xml_attr*)attr; 
    382403            } else { 
    383                 return attr; 
     404                return (pj_xml_attr*)attr; 
    384405            } 
    385406        } 
     
    391412 
    392413 
    393 PJ_DEF(pj_xml_node*) pj_xml_find( pj_xml_node *parent, const pj_str_t *name, 
     414PJ_DEF(pj_xml_node*) pj_xml_find( const pj_xml_node *parent,  
     415                                  const pj_str_t *name, 
    394416                                  const void *data,  
    395                                   pj_bool_t (*match)(pj_xml_node *, const void*)) 
    396 { 
    397     pj_xml_node *head = (pj_xml_node*) &parent->node_head, *node = head->next; 
    398  
    399     while (node != (void*)head) { 
    400         if (name && pj_stricmp(&node->name, name)==0) { 
    401             if (match) { 
    402                 if (match(node, data)) 
    403                     return node; 
    404             } else { 
    405                 return node; 
     417                                  pj_bool_t (*match)(const pj_xml_node *,  
     418                                                     const void*)) 
     419{ 
     420    const pj_xml_node *node = (const pj_xml_node *)parent->node_head.next; 
     421 
     422    if (!name && !match) 
     423        return NULL; 
     424 
     425    while (node != (const pj_xml_node*) &parent->node_head) { 
     426        if (name) { 
     427            if (pj_stricmp(&node->name, name)!=0) { 
     428                node = node->next; 
     429                continue; 
    406430            } 
    407431        } 
     432        if (match) { 
     433            if (match(node, data)) 
     434                return (pj_xml_node*)node; 
     435        } else { 
     436            return (pj_xml_node*)node; 
     437        } 
     438 
    408439        node = node->next; 
    409440    } 
     
    411442} 
    412443 
     444PJ_DEF(pj_xml_node*) pj_xml_find_rec( const pj_xml_node *parent,  
     445                                      const pj_str_t *name, 
     446                                      const void *data,  
     447                                      pj_bool_t (*match)(const pj_xml_node*,  
     448                                                         const void*)) 
     449{ 
     450    const pj_xml_node *node = (const pj_xml_node *)parent->node_head.next; 
     451 
     452    if (!name && !match) 
     453        return NULL; 
     454 
     455    while (node != (const pj_xml_node*) &parent->node_head) { 
     456        pj_xml_node *found; 
     457 
     458        if (name) { 
     459            if (pj_stricmp(&node->name, name)==0) { 
     460                if (match) { 
     461                    if (match(node, data)) 
     462                        return (pj_xml_node*)node; 
     463                } else { 
     464                    return (pj_xml_node*)node; 
     465                } 
     466            } 
     467 
     468        } else if (match) { 
     469            if (match(node, data)) 
     470                return (pj_xml_node*)node; 
     471        } 
     472 
     473        found = pj_xml_find_rec(node, name, data, match); 
     474        if (found) 
     475            return found; 
     476 
     477        node = node->next; 
     478    } 
     479    return NULL; 
     480} 
    413481 
    414482PJ_DEF(pj_xml_node*) pj_xml_clone( pj_pool_t *pool, const pj_xml_node *rhs) 
Note: See TracChangeset for help on using the changeset viewer.