Ticket #868: Added functions to search XML child nodes recursively
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2727 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
9f25ec0187
commit
ecc183e9be
|
@ -149,17 +149,18 @@ PJ_DECL(void) pj_xml_add_node( pj_xml_node *parent, pj_xml_node *node );
|
|||
PJ_DECL(void) pj_xml_add_attr( pj_xml_node *node, pj_xml_attr *attr );
|
||||
|
||||
/**
|
||||
* Find first node with the specified name.
|
||||
* Find first direct child node with the specified name.
|
||||
*
|
||||
* @param parent Parent node.
|
||||
* @param name Node name to find.
|
||||
*
|
||||
* @return XML node found or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find_node(pj_xml_node *parent, const pj_str_t *name);
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find_node(const pj_xml_node *parent,
|
||||
const pj_str_t *name);
|
||||
|
||||
/**
|
||||
* Find first node with the specified name.
|
||||
* Find next direct child node with the specified name.
|
||||
*
|
||||
* @param parent Parent node.
|
||||
* @param node node->next is the starting point.
|
||||
|
@ -167,11 +168,26 @@ PJ_DECL(pj_xml_node*) pj_xml_find_node(pj_xml_node *parent, const pj_str_t *name
|
|||
*
|
||||
* @return XML node found or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find_next_node(pj_xml_node *parent, pj_xml_node *node,
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find_next_node(const pj_xml_node *parent,
|
||||
const pj_xml_node *node,
|
||||
const pj_str_t *name);
|
||||
|
||||
/**
|
||||
* Find first attribute within a node with the specified name and optional value.
|
||||
* Recursively find the first node with the specified name in the child nodes
|
||||
* and their children.
|
||||
*
|
||||
* @param parent Parent node.
|
||||
* @param name Node name to find.
|
||||
*
|
||||
* @return XML node found or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find_node_rec(const pj_xml_node *parent,
|
||||
const pj_str_t *name);
|
||||
|
||||
|
||||
/**
|
||||
* Find first attribute within a node with the specified name and optional
|
||||
* value.
|
||||
*
|
||||
* @param node XML Node.
|
||||
* @param name Attribute name to find.
|
||||
|
@ -179,7 +195,8 @@ PJ_DECL(pj_xml_node*) pj_xml_find_next_node(pj_xml_node *parent, pj_xml_node *no
|
|||
*
|
||||
* @return XML attribute found, or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_attr*) pj_xml_find_attr(pj_xml_node *node, const pj_str_t *name,
|
||||
PJ_DECL(pj_xml_attr*) pj_xml_find_attr(const pj_xml_node *node,
|
||||
const pj_str_t *name,
|
||||
const pj_str_t *value);
|
||||
|
||||
|
||||
|
@ -187,15 +204,37 @@ PJ_DECL(pj_xml_attr*) pj_xml_find_attr(pj_xml_node *node, const pj_str_t *name,
|
|||
* Find a direct child node with the specified name and match the function.
|
||||
*
|
||||
* @param parent Parent node.
|
||||
* @param name Optional name.
|
||||
* @param name Optional name. If this is NULL, the name will not be
|
||||
* matched.
|
||||
* @param data Data to be passed to matching function.
|
||||
* @param match Optional matching function.
|
||||
*
|
||||
* @return The first matched node, or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find( pj_xml_node *parent, const pj_str_t *name,
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find( const pj_xml_node *parent,
|
||||
const pj_str_t *name,
|
||||
const void *data,
|
||||
pj_bool_t (*match)(pj_xml_node *, const void*));
|
||||
pj_bool_t (*match)(const pj_xml_node *,
|
||||
const void*));
|
||||
|
||||
|
||||
/**
|
||||
* Recursively find a child node with the specified name and match the
|
||||
* function.
|
||||
*
|
||||
* @param parent Parent node.
|
||||
* @param name Optional name. If this is NULL, the name will not be
|
||||
* matched.
|
||||
* @param data Data to be passed to matching function.
|
||||
* @param match Optional matching function.
|
||||
*
|
||||
* @return The first matched node, or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find_rec(const pj_xml_node *parent,
|
||||
const pj_str_t *name,
|
||||
const void *data,
|
||||
pj_bool_t (*match)(const pj_xml_node*,
|
||||
const void*));
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -340,22 +340,42 @@ PJ_DEF(void) pj_xml_add_attr( pj_xml_node *node, pj_xml_attr *attr )
|
|||
pj_list_push_back(&node->attr_head, attr);
|
||||
}
|
||||
|
||||
PJ_DEF(pj_xml_node*) pj_xml_find_node(pj_xml_node *parent, const pj_str_t *name)
|
||||
PJ_DEF(pj_xml_node*) pj_xml_find_node(const pj_xml_node *parent,
|
||||
const pj_str_t *name)
|
||||
{
|
||||
pj_xml_node *node = parent->node_head.next;
|
||||
const pj_xml_node *node = parent->node_head.next;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
while (node != (void*)&parent->node_head) {
|
||||
if (pj_stricmp(&node->name, name) == 0)
|
||||
return node;
|
||||
return (pj_xml_node*)node;
|
||||
node = node->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PJ_DEF(pj_xml_node*) pj_xml_find_node_rec(const pj_xml_node *parent,
|
||||
const pj_str_t *name)
|
||||
{
|
||||
const pj_xml_node *node = parent->node_head.next;
|
||||
|
||||
PJ_DEF(pj_xml_node*) pj_xml_find_next_node( pj_xml_node *parent, pj_xml_node *node,
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
while (node != (void*)&parent->node_head) {
|
||||
pj_xml_node *found;
|
||||
if (pj_stricmp(&node->name, name) == 0)
|
||||
return (pj_xml_node*)node;
|
||||
found = pj_xml_find_node_rec(node, name);
|
||||
if (found)
|
||||
return (pj_xml_node*)found;
|
||||
node = node->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PJ_DEF(pj_xml_node*) pj_xml_find_next_node( const pj_xml_node *parent,
|
||||
const pj_xml_node *node,
|
||||
const pj_str_t *name)
|
||||
{
|
||||
PJ_CHECK_STACK();
|
||||
|
@ -363,24 +383,25 @@ PJ_DEF(pj_xml_node*) pj_xml_find_next_node( pj_xml_node *parent, pj_xml_node *no
|
|||
node = node->next;
|
||||
while (node != (void*)&parent->node_head) {
|
||||
if (pj_stricmp(&node->name, name) == 0)
|
||||
return node;
|
||||
return (pj_xml_node*)node;
|
||||
node = node->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
PJ_DEF(pj_xml_attr*) pj_xml_find_attr( pj_xml_node *node, const pj_str_t *name,
|
||||
PJ_DEF(pj_xml_attr*) pj_xml_find_attr( const pj_xml_node *node,
|
||||
const pj_str_t *name,
|
||||
const pj_str_t *value)
|
||||
{
|
||||
pj_xml_attr *attr = node->attr_head.next;
|
||||
const pj_xml_attr *attr = node->attr_head.next;
|
||||
while (attr != (void*)&node->attr_head) {
|
||||
if (pj_stricmp(&attr->name, name)==0) {
|
||||
if (value) {
|
||||
if (pj_stricmp(&attr->value, value)==0)
|
||||
return attr;
|
||||
return (pj_xml_attr*)attr;
|
||||
} else {
|
||||
return attr;
|
||||
return (pj_xml_attr*)attr;
|
||||
}
|
||||
}
|
||||
attr = attr->next;
|
||||
|
@ -390,26 +411,73 @@ PJ_DEF(pj_xml_attr*) pj_xml_find_attr( pj_xml_node *node, const pj_str_t *name,
|
|||
|
||||
|
||||
|
||||
PJ_DEF(pj_xml_node*) pj_xml_find( pj_xml_node *parent, const pj_str_t *name,
|
||||
PJ_DEF(pj_xml_node*) pj_xml_find( const pj_xml_node *parent,
|
||||
const pj_str_t *name,
|
||||
const void *data,
|
||||
pj_bool_t (*match)(pj_xml_node *, const void*))
|
||||
pj_bool_t (*match)(const pj_xml_node *,
|
||||
const void*))
|
||||
{
|
||||
pj_xml_node *head = (pj_xml_node*) &parent->node_head, *node = head->next;
|
||||
const pj_xml_node *node = (const pj_xml_node *)parent->node_head.next;
|
||||
|
||||
while (node != (void*)head) {
|
||||
if (name && pj_stricmp(&node->name, name)==0) {
|
||||
if (match) {
|
||||
if (match(node, data))
|
||||
return node;
|
||||
} else {
|
||||
return node;
|
||||
if (!name && !match)
|
||||
return NULL;
|
||||
|
||||
while (node != (const pj_xml_node*) &parent->node_head) {
|
||||
if (name) {
|
||||
if (pj_stricmp(&node->name, name)!=0) {
|
||||
node = node->next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
if (match(node, data))
|
||||
return (pj_xml_node*)node;
|
||||
} else {
|
||||
return (pj_xml_node*)node;
|
||||
}
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PJ_DEF(pj_xml_node*) pj_xml_find_rec( const pj_xml_node *parent,
|
||||
const pj_str_t *name,
|
||||
const void *data,
|
||||
pj_bool_t (*match)(const pj_xml_node*,
|
||||
const void*))
|
||||
{
|
||||
const pj_xml_node *node = (const pj_xml_node *)parent->node_head.next;
|
||||
|
||||
if (!name && !match)
|
||||
return NULL;
|
||||
|
||||
while (node != (const pj_xml_node*) &parent->node_head) {
|
||||
pj_xml_node *found;
|
||||
|
||||
if (name) {
|
||||
if (pj_stricmp(&node->name, name)==0) {
|
||||
if (match) {
|
||||
if (match(node, data))
|
||||
return (pj_xml_node*)node;
|
||||
} else {
|
||||
return (pj_xml_node*)node;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (match) {
|
||||
if (match(node, data))
|
||||
return (pj_xml_node*)node;
|
||||
}
|
||||
|
||||
found = pj_xml_find_rec(node, name, data, match);
|
||||
if (found)
|
||||
return found;
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PJ_DEF(pj_xml_node*) pj_xml_clone( pj_pool_t *pool, const pj_xml_node *rhs)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue