Select from a map of subnodes (from a call to hzXmlNode::MapAllSubnodes) according to the supplied criteria. The criteria is of the form tagname...tagname->param=value in which the parameter value could be missing, both the parameter and the value coule be missing and the tagname may be singular. The tagname (if multiple) will be applied in reverse order. A node will be selected only if it's name matches the last tagname and it has a parent whose name matches the last but one tagname and a grandparent whose name matches the last but two tagname and so on until there are no more tagnames to apply. 1) tagname 2) level0tagname...levelNtagname 3) ....tagname="some value" 4) ....tagname->attribute 5) ....tagname->attribute="some value" The criteria must only serve to identify a single tag or tag attribute. All nodes matching matching this criteria are then compiled into the supplied hzVect. Note that only the nodes will be placed in the vector and not the attributes. The application will have to use the hzXmlNode member fuctions for accessing attributes and there values if these are required.
| Return Type | Function name | Arguments |
|---|---|---|
| hzEcode | hzXmlNode::SelectSubnodes | (hzVect<hzXmlNode*>&,hzMapM<hzString,hzXmlNode*>&,const char*,) |
Declared in file: hzDocument.h
Defined in file : hzDocXml.cpp
Function Logic:
Function body:
hzEcode hzXmlNode::SelectSubnodes (hzVect<hzXmlNode*>& result)hzMapM<hzString,hzXmlNode*>& allsubnodes, const char* criteria,
{
// Select from a map of subnodes (from a call to hzXmlNode::MapAllSubnodes) according to the supplied criteria.
//
// The criteria is of the form tagname...tagname->param=value in which the parameter value could be missing, both
// the parameter and the value coule be missing and the tagname may be singular. The tagname (if multiple) will be
// applied in reverse order. A node will be selected only if it's name matches the last tagname and it has a parent
// whose name matches the last but one tagname and a grandparent whose name matches the last but two tagname and so
// on until there are no more tagnames to apply.
//
// 1) tagname
// 2) level0tagname...levelNtagname
// 3) ....tagname="some value"
// 4) ....tagname->attribute
// 5) ....tagname->attribute="some value"
//
// The criteria must only serve to identify a single tag or tag attribute. All nodes matching
// matching this criteria are then compiled into the supplied hzVect. Note that only the
// nodes will be placed in the vector and not the attributes. The application will have to
// use the hzXmlNode member fuctions for accessing attributes and there values if these are
// required.
//
// Arguments: 1) result Vector of selected nodes
// 2) subnodes Map of subnodes from which to select into result
// 3) criteria Selection criteria
//
// Returns: E_NODATA If there are no subnodes
// E_OK If subnodes are selected
_hzfunc("hzXmlNode::SelectSubnodes") ;
hzVect<hzString> ar ; // List of tagnames to be applied in reverse
hzXmlNode* pnode ; // Node pointer
const char* i ; // Char iterator
const char* j ; // Buffer populator
hzString S ; // The partial tagname
uint32_t nIndex ; // Iterator
uint32_t nLo ; // Iterator to first matching node
uint32_t nHi ; // Iterator to first matching node
uint32_t nX ; // Iterator between first and last
result.Clear() ;
// Check input data
if (!allsubnodes.Count())
return E_NODATA ;
// If no filter
if (!criteria || !criteria[0])
{
for (nIndex = 0; nIndex < allsubnodes.Count() ; nIndex++)
{
pnode = allsubnodes.GetObj(nIndex) ;
result.Add(pnode) ;
}
return E_OK ;
}
// Obtain the list of tagnames from the criteria.
for (j = i = criteria ; *i ; i++)
{
if (i[0]== CHAR_PERIOD)
{
// Make a name string and continue
S.SetValue(j, i) ;
ar.Add(S) ;
j = i + 1;
continue ;
}
if (i[0]== CHAR_EQUAL || (i[0]== CHAR_MINUS && i[1]== CHAR_MORE))
{
// Make a name string and break
S.SetValue(j, i) ;
ar.Add(S) ;
j = 0;
break ;
}
}
if (j)
{
S = j ;
ar.Add(S) ;
}
// Locate all nodes with name of last tagname
// Apply list of tagnames in reverse
for (nIndex = ar.Count() ; nIndex ; nIndex--)
{
S = ar[nIndex-1];
}
nLo = allsubnodes.First(S) ;
if (nLo < 0)
return E_NODATA ;
nHi = allsubnodes.Last(S) ;
for (nX = nLo ; nX <&eq; nHi ; nX++)
{
pnode = allsubnodes.GetObj(nX) ;
if (pnode->txtName() != S)
continue ;
// We now have a node with name match on last tagname. If there are no more tagnames we add this to the list
if (ar.Count() == 1)
{
result.Add(pnode) ;
continue ;
}
}
return E_OK ;
}