Find all nodes within an XML document meeting the supplied search expression. The critieria MUST as a minimum, specify the name of the XML nodes sought. The criteria can optionally specify an attribute the node must contain and can go on to require that the attribute has a particular value. In addition, node ancestry may be specified. The notation convention is to use the :: symbol between tags to show ancestry, the -> symbol to name the tag attribute and the = symbol to specify a tag attribute value. Criteria can thus be of the forms:- 1) tagname 2) level_N-1_tagname::level_N_tagname 3) ...tagname->attribute_name 4) ...tagname->attribute_name=attribute_value All nodes matching this criteria are added to the supplied vector and appear in their order of incidence in the XML document.

Return TypeFunction nameArguments
hzEcodehzDocXml::FindNodes(hzVect<hzXmlNode*>&,const char*,)

Declared in file: hzDocument.h
Defined in file : hzDocXml.cpp

Function Logic:

0:START 1:items 2:unknown 3:Return E_ARGUMENT 4:cpBuf 5:j 6:unknown 7:unknown 8:* j tagname 9:unknown 10:unknown 11:unknown 12:* j attrname 13:unknown 14:unknown 15:unknown 16:* value 17:cpBuf nLo 18:unknown 19:items 20:Return E_NOTFOUND 21:nHi 22:unknown 23:nodeNo pN bInclude 24:unknown 25:unknown 26:anam aval 27:unknown 28:unknown 29:bInclude 30:unknown 31:bInclude 32:unknown 33:items 34:Return E_OK

Function body:

hzEcode hzDocXml::FindNodes (hzVect<hzXmlNode*>& Nodes)const char* srchExp, 
{
   //  Find all nodes within an XML document meeting the supplied search expression.
   //  
   //  The critieria MUST as a minimum, specify the name of the XML nodes sought. The criteria can optionally specify an attribute the node must contain and can
   //  go on to require that the attribute has a particular value. In addition, node ancestry may be specified.
   //  
   //  The notation convention is to use the :: symbol between tags to show ancestry, the -> symbol to name the tag attribute and the = symbol to specify a tag
   //  attribute value. Criteria can thus be of the forms:-
   //  
   //   1) tagname
   //   2) level_N-1_tagname::level_N_tagname
   //   3) ...tagname->attribute_name
   //   4) ...tagname->attribute_name=attribute_value
   //  
   //  All nodes matching this criteria are added to the supplied vector and appear in their order of incidence in the XML document.
   //  
   //  Arguments: 1) Nodes Vector of nodes selected
   //     2) srchExp Selection criteria
   //  
   //  Returns: E_ARGUMENT If no selection criteria is supplied
   //     E_NOTFOUND If no nodes were selected
   //     E_OK  If nodes were selected
   _hzfunc("hzDocXml::FindNodes") ;
   hzAttrset       ai ;            //  Attribute iterator
   hzXmlNode*      pN ;            //  Node pointer
   const char*     anam ;          //  Name derived from string number
   const char*     aval ;          //  Attribute value
   const char*     i ;             //  Char iterator
   char*           j ;             //  Buffer populator
   char*           cpBuf ;         //  Buffer for breaking up criteria
   hzString        tagname ;       //  The part of the criteria needed to name the tag
   hzString        attrname ;      //  The part of the criteria needed to name the tag attribute
   hzString        value ;         //  The part of the criteria needed to specify node or node attribute values
   uint32_t        nodeNo ;        //  Node number
   uint32_t        nLo ;           //  First instance of tagname in m_AllNodes
   uint32_t        nHi ;           //  Last instance of tagname in m_AllNodes
   uint32_t        nIndex ;        //  Node iterator
   bool            bInclude ;      //  Node has passed criteria
   Nodes.Clear() ;
   if (!srchExp || !srchExp[0])
       return E_ARGUMENT ;
   /*
   **  ** Objain the tagname, any attribute name and value from the criteria
   **      */
   j = cpBuf = new char[strlen(srchExp) + 1];
   for (i = srchExp ; *i ; *j++ = *i++)
   {
       if (*i == CHAR_EQUAL || (*i == ''-''&&i[1]== ''>''))
           break ;
   }
   *j = 0;
   tagname = j = cpBuf ;
   if (i[0]== ''-''&&i[1]== ''>'')
   {
       for (i += 2; *i ; *j++ = *i++)
       {
           if (*i == CHAR_EQUAL)
               break ;
       }
       *j = 0;
       attrname = j = cpBuf ;
   }
   if (*i == CHAR_EQUAL)
   {
       for (i++ ; *i && *i != CHAR_DQUOTE ; i++) ;
       for (i++ ; *i && *i != CHAR_DQUOTE ; *j++ = *i++) ;
       *j = 0;
       value = cpBuf ;
   }
   delete cpBuf ;
   /*
   **  ** First obtain the nodes
   **      */
   nLo = m_NodesName.First(tagname) ;
   if (nLo < 0)
       { threadLog("Cannot locate a tag of [%s] in tree\n", *tagname) ; return E_NOTFOUND ; }
   nHi = m_NodesName.Last(tagname) ;
   for (nIndex = nLo ; nIndex <&eq; nHi ; nIndex++)
   {
       nodeNo = m_NodesName.GetObj(nIndex) ;
       pN = m_arrNodes.InSitu(nodeNo-1);
       bInclude = false ;
       if (attrname)
       {
           //  To qualify, the node must have an attribute named attrname. If there is also a specified
           //  value, then the attribute must be of this value.
           //  pAttr = pN->GetAttributes() ;
           //  for (nA = 0 ; nA < pN->GetNoAttrs() ; nA++)
           //  {
           //   anam = Xlate(pAttr[nA].snName) ;
           //   aval = Xlate(pAttr[nA].snValue) ;
           for (ai = pN ; ai.Valid() ; ai.Advance())
           {
               anam = ai.Name() ; aval = ai.Value() ;
               if (attrname == anam)
               {
                   //  We have the attribute, but if there is a value this must match as well
                   if (!value || value == aval)
                       bInclude = true ;
                   break ;
               }
           }
       }
       else
       {
           if (!value || pN->m_fixContent == value)
               bInclude = true ;
       }
       if (bInclude)
           Nodes.Add(pN) ;
   }
   return E_OK ;
}