Table of Content
HAL Forum
function string XmlGetAttributeName (
xml xml,string NodePath,integer AttributeNr)
Description:
Returns the attribute name of the specified XML node.
Parameters:
xml Parsed xml data
NodePath Path to the target node in the XML data in format "parent\child\grandchild\etc".
AttributeNr The linear position of the attribute inside the specified node tag (starting from 0)
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:
««