Table of Content
HAL Forum
function LongInt XmlCountChildren (
xml XMLData,string NodePath)
Description:
Returns the count of same level sub-nodes in the XML data.
Parameters:
XMLData Parsed XML data.
NodePath Path to the target node in the XML data in format "parent\child\grandchild\etc".
global
function string 255 BuildXPathWithXml(xml x,string inpath,string inns,boolean strictnsf)
begin
  string 255 node,mpath;
  string 255 ns,curpath,testpath;
  string 255 defns,ldefns;
  string 255 res;
  string 255 prefix,attr;
  string 255 childname,cprefix;
  string 255 lknownns;
  integer i,j,attrcnt,nodecnt;
  longint idx,foundcnt;
  vector string 255 vinputns;
  vector string 255 vknownns;
  vector string 255 vlknownns;
  
  mpath = inns;
  node = removenextlistitem(mpath,",");
  while (nonblank(node)) begin
    ns = removenextlistitem(node,"=");
    if (nonblank(ns)) then begin
      vinputns[ns] = node;
    end;
    node = removenextlistitem(mpath,",");
  end;
  
  mpath = inpath;
  node = removenextnode(mpath);
  while (nonblank(node)) begin
    ldefns = "";
    foundcnt = 0;
    
    SplitNodeArrayIndex(node,idx);

    SplitNodeNamePrefix(node,prefix);

    if (blank(prefix)) then begin
      testpath = ConcatXPath(curpath,node);
      if (idx!=-1) then begin
        testpath = testpath & "[" & idx & "]";
      end;
      attr = XmlGetAttribute(x,testpath,"xmlns");
      if (XmlNodeExists(x,testpath)) then begin
        if (strictnsf==false or (blank(attr) and blank(defns))) then begin
          goto Lmatch;
        end;
      end;
      if (strictnsf) then begin
        goto Lerror;
      end;
    end;

    nodecnt = XmlCountChildren(x,curpath);
    for (i=0;i<nodecnt;i=i+1) begin
      lknownns = "";
      
      ldefns = defns;
      
      childname = XmlGetChildName(x,curpath,i);

      if (childname=="?xml") then begin
        goto Lnextchild;
      end;

      testpath = ConcatXPath(curpath,childname);

      SplitNodeNamePrefix(childname,cprefix);

      if (strictnsf==false) then begin
        if (node==childname) then begin
          goto Lfound;
        end;
        goto Lnextchild;
      end;

      attrcnt = XmlCountAttributes(x,testpath);
      for (j=0;j<attrcnt;j=j+1) begin
        attr = XmlGetAttributeName(x,testpath,j);

        if (left(attr,6)=="xmlns:") then begin
          ns = right(attr,len(attr)-6);
          lknownns = lknownns & ns & ",";

          vlknownns[ns] = XmlGetAttribute(x,testpath,attr);
        end else begin
          if (attr=="xmlns") then begin
            ldefns = XmlGetAttribute(x,testpath,attr);
          end;
        end;
      end;

      if (blank(cprefix)) then begin
        if (vinputns[prefix]==ldefns) then begin
          goto Lfound;
        end;
        goto Lnextchild;
      end;

      ns = "";
      if (SetInSet(cprefix,lknownns)) then begin
        ns = vlknownns[cprefix];
      end else begin
        ns = vknownns[cprefix];
      end;

      if (vinputns[prefix]==ns) then begin
        goto Lfound;
      end;
      
      goto Lnextchild;

Lfound:;
      if (idx==-1) then begin
        goto Lmatch;
      end else begin
        if (foundcnt==idx) then begin
          goto Lmatch;
        end else begin
          foundcnt = foundcnt + 1;
        end;
      end;

Lnextchild:;
    end;
    
    goto Lerror;
    
Lmatch:;
    curpath = testpath;

    ns = removenextlistitem(lknownns,",");
    while (nonblank(ns)) begin
      vknownns[ns] = vlknownns[ns];
      ns = removenextlistitem(lknownns,",");
    end;

    if (nonblank(ldefns)) then begin
      defns = ldefns;
    end;

    node = removenextnode(mpath);
  end;
  
  res = curpath;

Lerror:;
  BuildXPathWithXml = res;
  return;
end;
Related topics:
««