Thread: XML Parser
View Single Post
  #5  
Old 08-24-2006, 05:22 AM
Tolnaftate2004 Tolnaftate2004 is offline
penguin.
Join Date: Jul 2004
Location: Berkeley, CA
Posts: 534
Tolnaftate2004 is a jewel in the roughTolnaftate2004 is a jewel in the rough
Send a message via AIM to Tolnaftate2004
Quote:
Originally Posted by ApothiX
Wouldn't it work if you did it like this:
PHP Code:
me = new TStaticVar();
me parseXML(blahblah); 
?
No, parseXML just returns blahblah, so in effect I'd have just parsed some crazy string to come up with me = blahblah. It is written that way so that 'me' is given the properties stated above.

e:
PHP Code:
function parseXML(strXML) {
  ERROR = NULL;
    ERROR.NO_CLOSE_TAG = "There is no closing tag for tag <%s>.";
    ERROR.NO_CLOSE_ENT = "An entity was not terminated.";
    ERROR.XML_DECL_END = "The XML declaration was not terminated properly.";
    ERROR.COMMENT_END  = "A comment was never terminated.";
    ERROR.IMPROP_FORM  = "The XML file is improperly formed.";
  temp.xml = strXML;
  this.childNodes = new [0];
  temp.intOTag = temp.xml.pos("<");
  if (~temp.intOTag) temp.intETag = getEndIndex(temp.xml,">");
  temp.intPrev = -1;
  if (temp.intOTag == -1) {
    this.childNodes.add(temp.xml);
    this.childNodes[++temp.intPrev].nodeType = 1;
  } else {
    while (temp.intOTag > -1) {
      if (temp.intOTag > 0) {
        this.childNodes.add(temp.xml.substring(0,temp.intOTag));
        this.childNodes[++temp.intPrev].nodeType = 1;
        this.childNodes[temp.intPrev].parent = this;
        temp.xml = temp.xml.substring(temp.intOTag);
        temp.intOTag = temp.xml.pos("<");
        if (~temp.intOTag) temp.intETag = getEndIndex(temp.xml,">");
      }
      temp.strTag = temp.xml.substring(1,temp.intETag-1);
      temp.strTagName = temp.strTag.substring(0,temp.strTag.pos(" ")).trim();
      temp.strTag = temp.strTag.substring(temp.strTagName.length());
      this.childNodes[temp.intPrev].nodeName = temp.strTagName;
      if (!temp.strTagName.starts("?xml") && temp.strTagname != "!DOCTYPE" && !temp.strTagName.starts("!--") && !temp.strTagName.starts("!CDATA[")) {
        if (!temp.strTagName.starts("/")) {
          if (temp.strTag != " /") {
          temp.xml = temp.xml.substring(temp.intETag+1);
          temp.strXMLCopy = temp.xml;
          temp.intDepth = 1;
          do {
            temp.intOPos = temp.strXMLCopy.pos("<" @ temp.strTagName);
            temp.intEPos = temp.strXMLCopy.pos("</" @ temp.strTagName @ ">");
            if (temp.intOPos == -1) temp.intOPos = temp.strXMLCopy.length()+1;
            if (temp.intEPos == -1) produce_error(ERROR.NO_CLOSE_TAG,temp.strTagName);
            switch (temp.intOPos < temp.intEPos) {
              case true:
                temp.intDepth ++;
                temp.strXMLCopy = temp.strXMLCopy.substring(temp.strXMLCopy.substring(temp.intOPos+1).pos(">")+1);
                break;
              case false:
                temp.intDepth --;
                temp.strXMLCopy = temp.strXMLCopy.substring(temp.strXMLCopy.substring(temp.intEPos+1).pos(">")+1);
                break;
            }
          } while (temp.intDepth > 0);
          temp.strChild = temp.xml.substring(0,temp.intEPos);
          temp.xml = temp.xml.substring(temp.intEPos+3+temp.strTagName.length());
          this.childNodes.add("<" @ temp.strTagName @ temp.strTag @ ">" @ temp.strChild @ "</" @ temp.strTagName @ ">");
          with(this.childNodes[++temp.intPrev]) parseXML(temp.strChild);
          this.childNodes[temp.intPrev].nodeType = 2;
          this.childNodes[temp.intPrev].nodeName = temp.strTagName;
          this.childNodes[temp.intPrev].parent = this;
          this.childNodes[temp.intPrev].nodeValue = temp.strChild;
        } else {
          this.childNodes.add("<" @ temp.strTagName @ temp.strTag @ ">");
          this.childNodes[++temp.intPrev].nodeName = temp.strTagName;
          this.childNodes[temp.intPrev].nodeType = 2;
          this.childNodes[temp.intPrev].parent = this;
          temp.xml = temp.xml.substring(temp.intETag+1);
        }
        with(this.childNodes[temp.intPrev].attributes) getAttributes(temp.strTag);
        } else produce_error(ERROR.IMPROP_FORM);
      } else {
        switch (temp.strTagName) {
          case "?xml":
            temp.intETag = temp.xml.pos("?>");
            if (intETag == -1) produce_error(ERROR.XML_DECL_END);
            temp.strTag = temp.xml.substring(5,temp.intETag-5);
            this.xmlDecl = "<?xml" @ temp.strTag @ "?>";
            with (this.xmlDecl.attributes) getAttributes(temp.strTag);
            break;
          case "!DOCTYPE":
            this.docTypeDecl = "<!DOCTYPE" @ temp.strTag @ ">";
            break;
        }
        if (temp.strTagName == "!--") {
          temp.pos = temp.xml.pos("-->");
          if (temp.pos > -1) temp.intETag = temp.pos + 2;
          else produce_error(ERROR.COMMENT_END);
        }
        elseif (temp.strTagName == "!CDATA[") {
          temp.pos = temp.xml.pos("]>");
          if (temp.pos > -1) temp.intETag = temp.pos + 1;
          else produce_error(ERROR.COMMENT_END);
        }
        temp.xml = temp.xml.substring(temp.intETag+1);
      }
      temp.intOTag = temp.xml.pos("<");
      if (~temp.intOTag) temp.intETag = getEndIndex(temp.xml,">");
    }
    if (temp.xml.length() > 0) {
      this.childNodes.add(temp.xml);
      this.childNodes[temp.intPrev].nodeType = 1;
      this.childNodes[temp.intPrev].parent = this;
      temp.xml = "";
    }
  }
  return strXML;
}

function getAttributes(strTag) {
  temp.arr = "";
  while(strTag.length() > 0) {
    strTag = strTag.trim();
    temp.pos = strTag.pos("=");
    if (temp.pos > -1) {
      temp.var = strTag.substring(0,temp.pos);
      if (strTag.charat(temp.pos+1) == char(34)) {
        temp.npos = strTag.substring(temp.pos+2).pos(char(34) @ " ");
        temp.len = strTag.substring(temp.pos+2).length();
        if (temp.npos == -1 && strTag.substring(temp.pos+2).substring(temp.len-1,1) == char(34)) temp.npos = temp.len-1;
      }
      else temp.npos = strTag.substring(temp.pos+2).pos(" ");
      temp.val = strTag.substring(temp.pos+2,temp.npos);
      this.(@temp.var) = temp.val;
      temp.arr.add(temp.var @ "=" @ temp.val);
      strTag = strTag.substring(temp.npos+temp.pos+3).trim();
    } else strTag = "";
  }
  temp.len = temp.arr.size();
  temp.str = temp.arr[0];
  for (temp.i=1;temp.i<temp.len;temp.i++)
    temp.str @= "&" @ temp.arr[temp.i];
  this = temp.str;
  return;
}

function getEndIndex(strXML,endtag) {
  temp.olen = 0;
  while (1) { // We'll return directly from inside
    temp.test = strXML.pos(endtag);
    if (temp.test == -1) {
      produce_error(ERROR.NO_CLOSE_ENT);
      return -1;
    }
    temp.before = strXML.substring(temp.test);
    temp.open = 0;
    do {
      temp.pos = temp.before.pos("=\"");
      if (temp.pos > -1) {
        temp.before = temp.before.substring(temp.pos+2);
        temp.open = 1;
        temp.pos = temp.before.pos("\" ");
        if (temp.pos > -1) {
          temp.before = temp.before.substring(temp.pos+2);
          temp.open = 0;
        } elseif (temp.before.substring(temp.before.length()-1,1) == "\"") {
          // \"
          temp.before = "";
          temp.open = 0;
        }
      }
    } while(temp.pos > -1 && temp.open == 0);
    if (temp.open == 1) {
      strXML = strXML.substring(temp.test+endtag.length());
      temp.olen += temp.test+endtag.length();
    } else return temp.olen + temp.test;
  }
  return -1; // 1 != true ?
}

function produce_error(strError) {
  echo(format(strError,params.subarray(1)));
  return;
}
Some bug fixes:
  • The xml declaration looks for the '?>' closing tag.
  • Quotes next to the closing tag are removed.
  • attributes can contain '>' now.

Some additions:
  • Error messages.
  • XML.nodeType now works for all nodes (I had originally scripted it to be XML.type and some of the .type code was still there. They were also never read-only at all, it seems.
__________________
◕‿‿◕ · pfa · check yer syntax! · src

Killa Be: when i got that locker in 6th grade the only thing in it was a picture of a midget useing a firehose :/

Last edited by Tolnaftate2004; 08-24-2006 at 08:47 PM..
Reply With Quote