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 Type | Function name | Arguments |
|---|---|---|
| hzEcode | hzDocXml::FindNodes | (hzVect<hzXmlNode*>&,const char*,) |
Declared in file: hzDocument.h
Defined in file : hzDocXml.cpp
Function Logic:
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 ;
}