lib/rhack/js/browser/xmlsax.js in rhack-1.2.1 vs lib/rhack/js/browser/xmlsax.js in rhack-1.2.7

- old
+ new

@@ -1,1564 +1,1564 @@ -// ========================================================================= -// -// xmlsax.js - an XML SAX parser in JavaScript. -// -// version 3.1 -// -// ========================================================================= -// -// Copyright (C) 2001 - 2002 David Joham (djoham@yahoo.com) and Scott Severtson -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. - -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// -// Visit the XML for <SCRIPT> home page at http://xmljs.sourceforge.net -// - -// CONSTANTS - -// ========================================================================= -// ========================================================================= -// ========================================================================= -var whitespace = "\n\r\t "; - - -/*************************************************************************************************************** -XMLP is a pull-based parser. The calling application passes in a XML string -to the constructor, then repeatedly calls .next() to parse the next segment. -.next() returns a flag indicating what type of segment was found, and stores -data temporarily in couple member variables (name, content, array of -attributes), which can be accessed by several .get____() methods. - -Basically, XMLP is the lowest common denominator parser - an very simple -API which other wrappers can be built against. -*****************************************************************************************************************/ - - -XMLP = function(strXML) { - /******************************************************************************************************************* - function: this is the constructor to the XMLP Object - - Author: Scott Severtson - - Description: - Instantiates and initializes the object - *********************************************************************************************************************/ - // Normalize line breaks - strXML = SAXStrings.replace(strXML, null, null, "\r\n", "\n"); - strXML = SAXStrings.replace(strXML, null, null, "\r", "\n"); - - this.m_xml = strXML; - this.m_iP = 0; - this.m_iState = XMLP._STATE_PROLOG; - this.m_stack = new Stack(); - this._clearAttributes(); - -} // end XMLP constructor - - -// CONSTANTS (these must be below the constructor) - -// ========================================================================= -// ========================================================================= -// ========================================================================= - -XMLP._NONE = 0; -XMLP._ELM_B = 1; -XMLP._ELM_E = 2; -XMLP._ELM_EMP = 3; -XMLP._ATT = 4; -XMLP._TEXT = 5; -XMLP._ENTITY = 6; -XMLP._PI = 7; -XMLP._CDATA = 8; -XMLP._COMMENT = 9; -XMLP._DTD = 10; -XMLP._ERROR = 11; - -XMLP._CONT_XML = 0; -XMLP._CONT_ALT = 1; - -XMLP._ATT_NAME = 0; -XMLP._ATT_VAL = 1; - -XMLP._STATE_PROLOG = 1; -XMLP._STATE_DOCUMENT = 2; -XMLP._STATE_MISC = 3; - -XMLP._errs = new Array(); -XMLP._errs[XMLP.ERR_CLOSE_PI = 0 ] = "PI: missing closing sequence"; -XMLP._errs[XMLP.ERR_CLOSE_DTD = 1 ] = "DTD: missing closing sequence"; -XMLP._errs[XMLP.ERR_CLOSE_COMMENT = 2 ] = "Comment: missing closing sequence"; -XMLP._errs[XMLP.ERR_CLOSE_CDATA = 3 ] = "CDATA: missing closing sequence"; -XMLP._errs[XMLP.ERR_CLOSE_ELM = 4 ] = "Element: missing closing sequence"; -XMLP._errs[XMLP.ERR_CLOSE_ENTITY = 5 ] = "Entity: missing closing sequence"; -XMLP._errs[XMLP.ERR_PI_TARGET = 6 ] = "PI: target is required"; -XMLP._errs[XMLP.ERR_ELM_EMPTY = 7 ] = "Element: cannot be both empty and closing"; -XMLP._errs[XMLP.ERR_ELM_NAME = 8 ] = "Element: name must immediatly follow \"<\""; -XMLP._errs[XMLP.ERR_ELM_LT_NAME = 9 ] = "Element: \"<\" not allowed in element names"; -XMLP._errs[XMLP.ERR_ATT_VALUES = 10] = "Attribute: values are required and must be in quotes"; -XMLP._errs[XMLP.ERR_ATT_LT_NAME = 11] = "Element: \"<\" not allowed in attribute names"; -XMLP._errs[XMLP.ERR_ATT_LT_VALUE = 12] = "Attribute: \"<\" not allowed in attribute values"; -XMLP._errs[XMLP.ERR_ATT_DUP = 13] = "Attribute: duplicate attributes not allowed"; -XMLP._errs[XMLP.ERR_ENTITY_UNKNOWN = 14] = "Entity: unknown entity"; -XMLP._errs[XMLP.ERR_INFINITELOOP = 15] = "Infininte loop"; -XMLP._errs[XMLP.ERR_DOC_STRUCTURE = 16] = "Document: only comments, processing instructions, or whitespace allowed outside of document element"; -XMLP._errs[XMLP.ERR_ELM_NESTING = 17] = "Element: must be nested correctly"; - -// ========================================================================= -// ========================================================================= -// ========================================================================= - - -XMLP.prototype._addAttribute = function(name, value) { - /******************************************************************************************************************* - function: _addAttribute - - Author: Scott Severtson - *********************************************************************************************************************/ - this.m_atts[this.m_atts.length] = new Array(name, value); -} // end function _addAttribute - - -XMLP.prototype._checkStructure = function(iEvent) { - /******************************************************************************************************************* - function: _checkStructure - - Author: Scott Severtson - *********************************************************************************************************************/ - - if(XMLP._STATE_PROLOG == this.m_iState) { - if((XMLP._TEXT == iEvent) || (XMLP._ENTITY == iEvent)) { - if(SAXStrings.indexOfNonWhitespace(this.getContent(), this.getContentBegin(), this.getContentEnd()) != -1) { - return this._setErr(XMLP.ERR_DOC_STRUCTURE); - } - } - - if((XMLP._ELM_B == iEvent) || (XMLP._ELM_EMP == iEvent)) { - this.m_iState = XMLP._STATE_DOCUMENT; - // Don't return - fall through to next state - } - } - if(XMLP._STATE_DOCUMENT == this.m_iState) { - if((XMLP._ELM_B == iEvent) || (XMLP._ELM_EMP == iEvent)) { - this.m_stack.push(this.getName()); - } - - if((XMLP._ELM_E == iEvent) || (XMLP._ELM_EMP == iEvent)) { - var strTop = this.m_stack.pop(); - if((strTop == null) || (strTop != this.getName())) { - return this._setErr(XMLP.ERR_ELM_NESTING); - } - } - - if(this.m_stack.count() == 0) { - this.m_iState = XMLP._STATE_MISC; - return iEvent; - } - } - if(XMLP._STATE_MISC == this.m_iState) { - if((XMLP._ELM_B == iEvent) || (XMLP._ELM_E == iEvent) || (XMLP._ELM_EMP == iEvent) || (XMLP.EVT_DTD == iEvent)) { - return this._setErr(XMLP.ERR_DOC_STRUCTURE); - } - - if((XMLP._TEXT == iEvent) || (XMLP._ENTITY == iEvent)) { - if(SAXStrings.indexOfNonWhitespace(this.getContent(), this.getContentBegin(), this.getContentEnd()) != -1) { - return this._setErr(XMLP.ERR_DOC_STRUCTURE); - } - } - } - - return iEvent; - -} // end function _checkStructure - - -XMLP.prototype._clearAttributes = function() { - /******************************************************************************************************************* - function: _clearAttributes - - Author: Scott Severtson - *********************************************************************************************************************/ - this.m_atts = new Array(); -} // end function _clearAttributes - - -XMLP.prototype._findAttributeIndex = function(name) { - /******************************************************************************************************************* - function: findAttributeIndex - - Author: Scott Severtson - *********************************************************************************************************************/ - for(var i = 0; i < this.m_atts.length; i++) { - if(this.m_atts[i][XMLP._ATT_NAME] == name) { - return i; - } - } - return -1; - -} // end function _findAttributeIndex - - -XMLP.prototype.getAttributeCount = function() { - /******************************************************************************************************************* - function: getAttributeCount - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_atts ? this.m_atts.length : 0; - -} // end function getAttributeCount() - - -XMLP.prototype.getAttributeName = function(index) { - /******************************************************************************************************************* - function: getAttributeName - - Author: Scott Severtson - *********************************************************************************************************************/ - - return ((index < 0) || (index >= this.m_atts.length)) ? null : this.m_atts[index][XMLP._ATT_NAME]; - -} //end function getAttributeName - - -XMLP.prototype.getAttributeValue = function(index) { - /******************************************************************************************************************* - function: getAttributeValue - - Author: Scott Severtson - *********************************************************************************************************************/ - - return ((index < 0) || (index >= this.m_atts.length)) ? null : __unescapeString(this.m_atts[index][XMLP._ATT_VAL]); - -} // end function getAttributeValue - - -XMLP.prototype.getAttributeValueByName = function(name) { - /******************************************************************************************************************* - function: getAttributeValueByName - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.getAttributeValue(this._findAttributeIndex(name)); - -} // end function getAttributeValueByName - - -XMLP.prototype.getColumnNumber = function() { - /******************************************************************************************************************* - function: getColumnNumber - - Author: Scott Severtson - *********************************************************************************************************************/ - - return SAXStrings.getColumnNumber(this.m_xml, this.m_iP); - -} // end function getColumnNumber - - -XMLP.prototype.getContent = function() { - /******************************************************************************************************************* - function: getContent - - Author: Scott Severtson - *********************************************************************************************************************/ - - return (this.m_cSrc == XMLP._CONT_XML) ? this.m_xml : this.m_cAlt; - -} //end function getContent - - -XMLP.prototype.getContentBegin = function() { - /******************************************************************************************************************* - function: getContentBegin - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_cB; - -} //end function getContentBegin - - -XMLP.prototype.getContentEnd = function() { - /******************************************************************************************************************* - function: getContentEnd - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_cE; - -} // end function getContentEnd - - -XMLP.prototype.getLineNumber = function() { - /******************************************************************************************************************* - function: getLineNumber - - Author: Scott Severtson - *********************************************************************************************************************/ - - return SAXStrings.getLineNumber(this.m_xml, this.m_iP); - -} // end function getLineNumber - - -XMLP.prototype.getName = function() { - /******************************************************************************************************************* - function: getName - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_name; - -} // end function getName() - - -XMLP.prototype.next = function() { - /******************************************************************************************************************* - function: next - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this._checkStructure(this._parse()); - -} // end function next() - - -XMLP.prototype._parse = function() { - /******************************************************************************************************************* - function: _parse - - Author: Scott Severtson - *********************************************************************************************************************/ - - if(this.m_iP == this.m_xml.length) { - return XMLP._NONE; - } - - if(this.m_iP == this.m_xml.indexOf("<?", this.m_iP)) { - return this._parsePI (this.m_iP + 2); - } - else if(this.m_iP == this.m_xml.indexOf("<!DOCTYPE", this.m_iP)) { - return this._parseDTD (this.m_iP + 9); - } - else if(this.m_iP == this.m_xml.indexOf("<!--", this.m_iP)) { - return this._parseComment(this.m_iP + 4); - } - else if(this.m_iP == this.m_xml.indexOf("<![CDATA[", this.m_iP)) { - return this._parseCDATA (this.m_iP + 9); - } - else if(this.m_iP == this.m_xml.indexOf("<", this.m_iP)) { - return this._parseElement(this.m_iP + 1); - } - else if(this.m_iP == this.m_xml.indexOf("&", this.m_iP)) { - return this._parseEntity (this.m_iP + 1); - } - else{ - return this._parseText (this.m_iP); - } - - -} // end function _parse - - -XMLP.prototype._parseAttribute = function(iB, iE) { - /******************************************************************************************************************* - function: _parseAttribute - - Author: Scott Severtson - *********************************************************************************************************************/ - var iNB, iNE, iEq, iVB, iVE; - var cQuote, strN, strV; - - this.m_cAlt = ""; //resets the value so we don't use an old one by accident (see testAttribute7 in the test suite) - - iNB = SAXStrings.indexOfNonWhitespace(this.m_xml, iB, iE); - if((iNB == -1) ||(iNB >= iE)) { - return iNB; - } - - iEq = this.m_xml.indexOf("=", iNB); - if((iEq == -1) || (iEq > iE)) { - return this._setErr(XMLP.ERR_ATT_VALUES); - } - - iNE = SAXStrings.lastIndexOfNonWhitespace(this.m_xml, iNB, iEq); - - iVB = SAXStrings.indexOfNonWhitespace(this.m_xml, iEq + 1, iE); - if((iVB == -1) ||(iVB > iE)) { - return this._setErr(XMLP.ERR_ATT_VALUES); - } - - cQuote = this.m_xml.charAt(iVB); - if(SAXStrings.QUOTES.indexOf(cQuote) == -1) { - return this._setErr(XMLP.ERR_ATT_VALUES); - } - - iVE = this.m_xml.indexOf(cQuote, iVB + 1); - if((iVE == -1) ||(iVE > iE)) { - return this._setErr(XMLP.ERR_ATT_VALUES); - } - - strN = this.m_xml.substring(iNB, iNE + 1); - strV = this.m_xml.substring(iVB + 1, iVE); - - if(strN.indexOf("<") != -1) { - return this._setErr(XMLP.ERR_ATT_LT_NAME); - } - - if(strV.indexOf("<") != -1) { - return this._setErr(XMLP.ERR_ATT_LT_VALUE); - } - - strV = SAXStrings.replace(strV, null, null, "\n", " "); - strV = SAXStrings.replace(strV, null, null, "\t", " "); - iRet = this._replaceEntities(strV); - if(iRet == XMLP._ERROR) { - return iRet; - } - - strV = this.m_cAlt; - - if(this._findAttributeIndex(strN) == -1) { - this._addAttribute(strN, strV); - } - else { - return this._setErr(XMLP.ERR_ATT_DUP); - } - - this.m_iP = iVE + 2; - - return XMLP._ATT; - -} // end function _parseAttribute - - -XMLP.prototype._parseCDATA = function(iB) { - /******************************************************************************************************************* - function: _parseCDATA - - Author: Scott Severtson - *********************************************************************************************************************/ - var iE = this.m_xml.indexOf("]]>", iB); - if (iE == -1) { - return this._setErr(XMLP.ERR_CLOSE_CDATA); - } - - this._setContent(XMLP._CONT_XML, iB, iE); - - this.m_iP = iE + 3; - - return XMLP._CDATA; - -} // end function _parseCDATA - - -XMLP.prototype._parseComment = function(iB) { - /******************************************************************************************************************* - function: _parseComment - - Author: Scott Severtson - *********************************************************************************************************************/ - var iE = this.m_xml.indexOf("-" + "->", iB); - if (iE == -1) { - return this._setErr(XMLP.ERR_CLOSE_COMMENT); - } - - this._setContent(XMLP._CONT_XML, iB, iE); - - this.m_iP = iE + 3; - - return XMLP._COMMENT; - -} // end function _parseComment - - -XMLP.prototype._parseDTD = function(iB) { - /******************************************************************************************************************* - function: _parseDTD - - Author: Scott Severtson - *********************************************************************************************************************/ - - // Eat DTD - - var iE, strClose, iInt, iLast; - - iE = this.m_xml.indexOf(">", iB); - if(iE == -1) { - return this._setErr(XMLP.ERR_CLOSE_DTD); - } - - iInt = this.m_xml.indexOf("[", iB); - strClose = ((iInt != -1) && (iInt < iE)) ? "]>" : ">"; - - while(true) { - // DEBUG: Remove - if(iE == iLast) { - return this._setErr(XMLP.ERR_INFINITELOOP); - } - - iLast = iE; - // DEBUG: Remove End - - iE = this.m_xml.indexOf(strClose, iB); - if(iE == -1) { - return this._setErr(XMLP.ERR_CLOSE_DTD); - } - - // Make sure it is not the end of a CDATA section - if (this.m_xml.substring(iE - 1, iE + 2) != "]]>") { - break; - } - } - - this.m_iP = iE + strClose.length; - - return XMLP._DTD; - -} // end function _parseDTD - - -XMLP.prototype._parseElement = function(iB) { - /******************************************************************************************************************* - function: _parseElement - - Author: Scott Severtson - *********************************************************************************************************************/ - var iE, iDE, iNE, iRet; - var iType, strN, iLast; - - iDE = iE = this.m_xml.indexOf(">", iB); - if(iE == -1) { - return this._setErr(XMLP.ERR_CLOSE_ELM); - } - - if(this.m_xml.charAt(iB) == "/") { - iType = XMLP._ELM_E; - iB++; - } else { - iType = XMLP._ELM_B; - } - - if(this.m_xml.charAt(iE - 1) == "/") { - if(iType == XMLP._ELM_E) { - return this._setErr(XMLP.ERR_ELM_EMPTY); - } - iType = XMLP._ELM_EMP; - iDE--; - } - - iDE = SAXStrings.lastIndexOfNonWhitespace(this.m_xml, iB, iDE); - - //djohack - //hack to allow for elements with single character names to be recognized - - if (iE - iB != 1 ) { - if(SAXStrings.indexOfNonWhitespace(this.m_xml, iB, iDE) != iB) { - return this._setErr(XMLP.ERR_ELM_NAME); - } - } - // end hack -- original code below - - /* - if(SAXStrings.indexOfNonWhitespace(this.m_xml, iB, iDE) != iB) - return this._setErr(XMLP.ERR_ELM_NAME); - */ - this._clearAttributes(); - - iNE = SAXStrings.indexOfWhitespace(this.m_xml, iB, iDE); - if(iNE == -1) { - iNE = iDE + 1; - } - else { - this.m_iP = iNE; - while(this.m_iP < iDE) { - // DEBUG: Remove - if(this.m_iP == iLast) return this._setErr(XMLP.ERR_INFINITELOOP); - iLast = this.m_iP; - // DEBUG: Remove End - - - iRet = this._parseAttribute(this.m_iP, iDE); - if(iRet == XMLP._ERROR) return iRet; - } - } - - strN = this.m_xml.substring(iB, iNE); - - if(strN.indexOf("<") != -1) { - return this._setErr(XMLP.ERR_ELM_LT_NAME); - } - - this.m_name = strN; - this.m_iP = iE + 1; - - return iType; - -} // end function _parseElement - - -XMLP.prototype._parseEntity = function(iB) { - /******************************************************************************************************************* - function: _parseEntity - - Author: Scott Severtson - *********************************************************************************************************************/ - var iE = this.m_xml.indexOf(";", iB); - if(iE == -1) { - return this._setErr(XMLP.ERR_CLOSE_ENTITY); - } - - this.m_iP = iE + 1; - - return this._replaceEntity(this.m_xml, iB, iE); - -} // end function _parseEntity - - -XMLP.prototype._parsePI = function(iB) { - /******************************************************************************************************************* - function: _parsePI - - Author: Scott Severtson - *********************************************************************************************************************/ - - var iE, iTB, iTE, iCB, iCE; - - iE = this.m_xml.indexOf("?>", iB); - if(iE == -1) { - return this._setErr(XMLP.ERR_CLOSE_PI); - } - - iTB = SAXStrings.indexOfNonWhitespace(this.m_xml, iB, iE); - if(iTB == -1) { - return this._setErr(XMLP.ERR_PI_TARGET); - } - - iTE = SAXStrings.indexOfWhitespace(this.m_xml, iTB, iE); - if(iTE == -1) { - iTE = iE; - } - - iCB = SAXStrings.indexOfNonWhitespace(this.m_xml, iTE, iE); - if(iCB == -1) { - iCB = iE; - } - - iCE = SAXStrings.lastIndexOfNonWhitespace(this.m_xml, iCB, iE); - if(iCE == -1) { - iCE = iE - 1; - } - - this.m_name = this.m_xml.substring(iTB, iTE); - this._setContent(XMLP._CONT_XML, iCB, iCE + 1); - this.m_iP = iE + 2; - - return XMLP._PI; - -} // end function _parsePI - - -XMLP.prototype._parseText = function(iB) { - /******************************************************************************************************************* - function: _parseText - - Author: Scott Severtson - *********************************************************************************************************************/ - var iE, iEE; - - iE = this.m_xml.indexOf("<", iB); - if(iE == -1) { - iE = this.m_xml.length; - } - - iEE = this.m_xml.indexOf("&", iB); - if((iEE != -1) && (iEE <= iE)) { - iE = iEE; - } - - this._setContent(XMLP._CONT_XML, iB, iE); - - this.m_iP = iE; - - return XMLP._TEXT; - -} // end function _parseText - - -XMLP.prototype._replaceEntities = function(strD, iB, iE) { - /******************************************************************************************************************* - function: _replaceEntities - - Author: Scott Severtson - *********************************************************************************************************************/ - if(SAXStrings.isEmpty(strD)) return ""; - iB = iB || 0; - iE = iE || strD.length; - - - var iEB, iEE, strRet = ""; - - iEB = strD.indexOf("&", iB); - iEE = iB; - - while((iEB > 0) && (iEB < iE)) { - strRet += strD.substring(iEE, iEB); - - iEE = strD.indexOf(";", iEB) + 1; - - if((iEE == 0) || (iEE > iE)) { - return this._setErr(XMLP.ERR_CLOSE_ENTITY); - } - - iRet = this._replaceEntity(strD, iEB + 1, iEE - 1); - if(iRet == XMLP._ERROR) { - return iRet; - } - - strRet += this.m_cAlt; - - iEB = strD.indexOf("&", iEE); - } - - if(iEE != iE) { - strRet += strD.substring(iEE, iE); - } - - this._setContent(XMLP._CONT_ALT, strRet); - - return XMLP._ENTITY; - -} // end function _replaceEntities - - -XMLP.prototype._replaceEntity = function(strD, iB, iE) { - /******************************************************************************************************************* - function: _replaceEntity - - Author: Scott Severtson - *********************************************************************************************************************/ - if(SAXStrings.isEmpty(strD)) return -1; - iB = iB || 0; - iE = iE || strD.length; - - switch(strD.substring(iB, iE)) { - case "amp": strEnt = "&"; break; - case "lt": strEnt = "<"; break; - case "gt": strEnt = ">"; break; - case "apos": strEnt = "'"; break; - case "quot": strEnt = "\""; break; - default: - if(strD.charAt(iB) == "#") { - strEnt = String.fromCharCode(parseInt(strD.substring(iB + 1, iE))); - } else { - return this._setErr(XMLP.ERR_ENTITY_UNKNOWN); - } - break; - } - this._setContent(XMLP._CONT_ALT, strEnt); - - return XMLP._ENTITY; -} // end function _replaceEntity - - -XMLP.prototype._setContent = function(iSrc) { - /******************************************************************************************************************* - function: _setContent - - Author: Scott Severtson - *********************************************************************************************************************/ - var args = arguments; - - if(XMLP._CONT_XML == iSrc) { - this.m_cAlt = null; - this.m_cB = args[1]; - this.m_cE = args[2]; - } else { - this.m_cAlt = args[1]; - this.m_cB = 0; - this.m_cE = args[1].length; - } - this.m_cSrc = iSrc; - -} // end function _setContent - - -XMLP.prototype._setErr = function(iErr) { - /******************************************************************************************************************* - function: _setErr - - Author: Scott Severtson - *********************************************************************************************************************/ - var strErr = XMLP._errs[iErr]; - - this.m_cAlt = strErr; - this.m_cB = 0; - this.m_cE = strErr.length; - this.m_cSrc = XMLP._CONT_ALT; - - return XMLP._ERROR; - -} // end function _setErr - - - - - - -/*************************************************************************************************************** -SAXDriver is an object that basically wraps an XMLP instance, and provides an -event-based interface for parsing. This is the object users interact with when coding -with XML for <SCRIPT> -*****************************************************************************************************************/ - - -SAXDriver = function() { - /******************************************************************************************************************* - function: SAXDriver - - Author: Scott Severtson - - Description: - This is the constructor for the SAXDriver Object - *********************************************************************************************************************/ - this.m_hndDoc = null; - this.m_hndErr = null; - this.m_hndLex = null; -} - - -// CONSTANTS (these must be below the constructor) - -// ========================================================================= -// ========================================================================= -// ========================================================================= -SAXDriver.DOC_B = 1; -SAXDriver.DOC_E = 2; -SAXDriver.ELM_B = 3; -SAXDriver.ELM_E = 4; -SAXDriver.CHARS = 5; -SAXDriver.PI = 6; -SAXDriver.CD_B = 7; -SAXDriver.CD_E = 8; -SAXDriver.CMNT = 9; -SAXDriver.DTD_B = 10; -SAXDriver.DTD_E = 11; -// ========================================================================= -// ========================================================================= -// ========================================================================= - - - -SAXDriver.prototype.parse = function(strD) { - /******************************************************************************************************************* - function: parse - - Author: Scott Severtson - *********************************************************************************************************************/ - var parser = new XMLP(strD); - - if(this.m_hndDoc && this.m_hndDoc.setDocumentLocator) { - this.m_hndDoc.setDocumentLocator(this); - } - - this.m_parser = parser; - this.m_bErr = false; - - if(!this.m_bErr) { - this._fireEvent(SAXDriver.DOC_B); - } - this._parseLoop(); - if(!this.m_bErr) { - this._fireEvent(SAXDriver.DOC_E); - } - - this.m_xml = null; - this.m_iP = 0; - -} // end function parse - - -SAXDriver.prototype.setDocumentHandler = function(hnd) { - /******************************************************************************************************************* - function: setDocumentHandler - - Author: Scott Severtson - *********************************************************************************************************************/ - - this.m_hndDoc = hnd; - -} // end function setDocumentHandler - - -SAXDriver.prototype.setErrorHandler = function(hnd) { - /******************************************************************************************************************* - function: setErrorHandler - - Author: Scott Severtson - *********************************************************************************************************************/ - - this.m_hndErr = hnd; - -} // end function setErrorHandler - - -SAXDriver.prototype.setLexicalHandler = function(hnd) { - /******************************************************************************************************************* - function: setLexicalHandler - - Author: Scott Severtson - *********************************************************************************************************************/ - - this.m_hndLex = hnd; - -} // end function setLexicalHandler - - - /******************************************************************************************************************* - LOCATOR/PARSE EXCEPTION INTERFACE - *********************************************************************************************************************/ - -SAXDriver.prototype.getColumnNumber = function() { - /******************************************************************************************************************* - function: getSystemId - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_parser.getColumnNumber(); - -} // end function getColumnNumber - - -SAXDriver.prototype.getLineNumber = function() { - /******************************************************************************************************************* - function: getLineNumber - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_parser.getLineNumber(); - -} // end function getLineNumber - - -SAXDriver.prototype.getMessage = function() { - /******************************************************************************************************************* - function: getMessage - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_strErrMsg; - -} // end function getMessage - - -SAXDriver.prototype.getPublicId = function() { - /******************************************************************************************************************* - function: getPublicID - - Author: Scott Severtson - *********************************************************************************************************************/ - - return null; - -} // end function getPublicID - - -SAXDriver.prototype.getSystemId = function() { - /******************************************************************************************************************* - function: getSystemId - - Author: Scott Severtson - *********************************************************************************************************************/ - - return null; - -} // end function getSystemId - - - /******************************************************************************************************************* - Attribute List Interface - *********************************************************************************************************************/ - -SAXDriver.prototype.getLength = function() { - /******************************************************************************************************************* - function: getLength - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_parser.getAttributeCount(); - -} // end function getAttributeCount - - -SAXDriver.prototype.getName = function(index) { - /******************************************************************************************************************* - function: getName - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_parser.getAttributeName(index); - -} // end function getAttributeName - - -SAXDriver.prototype.getValue = function(index) { - /******************************************************************************************************************* - function: getValue - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_parser.getAttributeValue(index); - -} // end function getAttributeValue - - -SAXDriver.prototype.getValueByName = function(name) { - /******************************************************************************************************************* - function: getValueByName - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_parser.getAttributeValueByName(name); - -} // end function getAttributeValueByName - - - /******************************************************************************************************************* - Private functions - *********************************************************************************************************************/ - -SAXDriver.prototype._fireError = function(strMsg) { - /******************************************************************************************************************* - function: _fireError - - Author: Scott Severtson - *********************************************************************************************************************/ - this.m_strErrMsg = strMsg; - this.m_bErr = true; - - if(this.m_hndErr && this.m_hndErr.fatalError) { - this.m_hndErr.fatalError(this); - } - -} // end function _fireError - - -SAXDriver.prototype._fireEvent = function(iEvt) { - /******************************************************************************************************************* - function: _fireEvent - - Author: Scott Severtson - *********************************************************************************************************************/ - var hnd, func, args = arguments, iLen = args.length - 1; - - if(this.m_bErr) return; - - if(SAXDriver.DOC_B == iEvt) { - func = "startDocument"; hnd = this.m_hndDoc; - } - else if (SAXDriver.DOC_E == iEvt) { - func = "endDocument"; hnd = this.m_hndDoc; - } - else if (SAXDriver.ELM_B == iEvt) { - func = "startElement"; hnd = this.m_hndDoc; - } - else if (SAXDriver.ELM_E == iEvt) { - func = "endElement"; hnd = this.m_hndDoc; - } - else if (SAXDriver.CHARS == iEvt) { - func = "characters"; hnd = this.m_hndDoc; - } - else if (SAXDriver.PI == iEvt) { - func = "processingInstruction"; hnd = this.m_hndDoc; - } - else if (SAXDriver.CD_B == iEvt) { - func = "startCDATA"; hnd = this.m_hndLex; - } - else if (SAXDriver.CD_E == iEvt) { - func = "endCDATA"; hnd = this.m_hndLex; - } - else if (SAXDriver.CMNT == iEvt) { - func = "comment"; hnd = this.m_hndLex; - } - - if(hnd && hnd[func]) { - if(0 == iLen) { - hnd[func](); - } - else if (1 == iLen) { - hnd[func](args[1]); - } - else if (2 == iLen) { - hnd[func](args[1], args[2]); - } - else if (3 == iLen) { - hnd[func](args[1], args[2], args[3]); - } - } - -} // end function _fireEvent - - -SAXDriver.prototype._parseLoop = function(parser) { - /******************************************************************************************************************* - function: _parseLoop - - Author: Scott Severtson - *********************************************************************************************************************/ - var iEvent, parser; - - parser = this.m_parser; - while(!this.m_bErr) { - iEvent = parser.next(); - - if(iEvent == XMLP._ELM_B) { - this._fireEvent(SAXDriver.ELM_B, parser.getName(), this); - } - else if(iEvent == XMLP._ELM_E) { - this._fireEvent(SAXDriver.ELM_E, parser.getName()); - } - else if(iEvent == XMLP._ELM_EMP) { - this._fireEvent(SAXDriver.ELM_B, parser.getName(), this); - this._fireEvent(SAXDriver.ELM_E, parser.getName()); - } - else if(iEvent == XMLP._TEXT) { - this._fireEvent(SAXDriver.CHARS, parser.getContent(), parser.getContentBegin(), parser.getContentEnd() - parser.getContentBegin()); - } - else if(iEvent == XMLP._ENTITY) { - this._fireEvent(SAXDriver.CHARS, parser.getContent(), parser.getContentBegin(), parser.getContentEnd() - parser.getContentBegin()); - } - else if(iEvent == XMLP._PI) { - this._fireEvent(SAXDriver.PI, parser.getName(), parser.getContent().substring(parser.getContentBegin(), parser.getContentEnd())); - } - else if(iEvent == XMLP._CDATA) { - this._fireEvent(SAXDriver.CD_B); - this._fireEvent(SAXDriver.CHARS, parser.getContent(), parser.getContentBegin(), parser.getContentEnd() - parser.getContentBegin()); - this._fireEvent(SAXDriver.CD_E); - } - else if(iEvent == XMLP._COMMENT) { - this._fireEvent(SAXDriver.CMNT, parser.getContent(), parser.getContentBegin(), parser.getContentEnd() - parser.getContentBegin()); - } - else if(iEvent == XMLP._DTD) { - } - else if(iEvent == XMLP._ERROR) { - this._fireError(parser.getContent()); - } - else if(iEvent == XMLP._NONE) { - return; - } - } - -} // end function _parseLoop - - - -/*************************************************************************************************************** -SAXStrings: a useful object containing string manipulation functions -*****************************************************************************************************************/ - - -SAXStrings = function() { - /******************************************************************************************************************* - function: SAXStrings - - Author: Scott Severtson - - Description: - This is the constructor of the SAXStrings object - *********************************************************************************************************************/ -} // end function SAXStrings - - -// CONSTANTS (these must be below the constructor) - -// ========================================================================= -// ========================================================================= -// ========================================================================= -SAXStrings.WHITESPACE = " \t\n\r"; -SAXStrings.QUOTES = "\"'"; -// ========================================================================= -// ========================================================================= -// ========================================================================= - - -SAXStrings.getColumnNumber = function(strD, iP) { - /******************************************************************************************************************* - function: replace - - Author: Scott Severtson - *********************************************************************************************************************/ - if(SAXStrings.isEmpty(strD)) { - return -1; - } - iP = iP || strD.length; - - var arrD = strD.substring(0, iP).split("\n"); - var strLine = arrD[arrD.length - 1]; - arrD.length--; - var iLinePos = arrD.join("\n").length; - - return iP - iLinePos; - -} // end function getColumnNumber - - -SAXStrings.getLineNumber = function(strD, iP) { - /******************************************************************************************************************* - function: getLineNumber - - Author: Scott Severtson - *********************************************************************************************************************/ - if(SAXStrings.isEmpty(strD)) { - return -1; - } - iP = iP || strD.length; - - return strD.substring(0, iP).split("\n").length -} // end function getLineNumber - - -SAXStrings.indexOfNonWhitespace = function(strD, iB, iE) { - /******************************************************************************************************************* - function: indexOfNonWhitespace - - Author: Scott Severtson - *********************************************************************************************************************/ - if(SAXStrings.isEmpty(strD)) { - return -1; - } - iB = iB || 0; - iE = iE || strD.length; - - for(var i = iB; i < iE; i++){ - if(SAXStrings.WHITESPACE.indexOf(strD.charAt(i)) == -1) { - return i; - } - } - return -1; - -} // end function indexOfNonWhitespace - - -SAXStrings.indexOfWhitespace = function(strD, iB, iE) { - /******************************************************************************************************************* - function: indexOfWhitespace - - Author: Scott Severtson - *********************************************************************************************************************/ - if(SAXStrings.isEmpty(strD)) { - return -1; - } - iB = iB || 0; - iE = iE || strD.length; - - for(var i = iB; i < iE; i++) { - if(SAXStrings.WHITESPACE.indexOf(strD.charAt(i)) != -1) { - return i; - } - } - return -1; -} // end function indexOfWhitespace - - -SAXStrings.isEmpty = function(strD) { - /******************************************************************************************************************* - function: isEmpty - - Author: Scott Severtson - *********************************************************************************************************************/ - - return (strD == null) || (strD.length == 0); - -} // end function isEmpty - - -SAXStrings.lastIndexOfNonWhitespace = function(strD, iB, iE) { - /******************************************************************************************************************* - function: lastIndexOfNonWhiteSpace - - Author: Scott Severtson - *********************************************************************************************************************/ - if(SAXStrings.isEmpty(strD)) { - return -1; - } - iB = iB || 0; - iE = iE || strD.length; - - for(var i = iE - 1; i >= iB; i--){ - if(SAXStrings.WHITESPACE.indexOf(strD.charAt(i)) == -1){ - return i; - } - } - return -1; -} // end function lastIndexOfNonWhitespace - - -SAXStrings.replace = function(strD, iB, iE, strF, strR) { - /******************************************************************************************************************* - function: replace - - Author: Scott Severtson - *********************************************************************************************************************/ - if(SAXStrings.isEmpty(strD)) { - return ""; - } - iB = iB || 0; - iE = iE || strD.length; - - return strD.substring(iB, iE).split(strF).join(strR); - -} // end function replace - - - -/*************************************************************************************************************** -Stack: A simple stack class, used for verifying document structure. -*****************************************************************************************************************/ - -Stack = function() { - /******************************************************************************************************************* - function: Stack - - Author: Scott Severtson - - Description: - Constructor of the Stack Object - *********************************************************************************************************************/ - this.m_arr = new Array(); - -} // end function Stack - - -Stack.prototype.clear = function() { - /******************************************************************************************************************* - function: clear - - Author: Scott Severtson - *********************************************************************************************************************/ - - this.m_arr = new Array(); - -} // end function clear - - -Stack.prototype.count = function() { - /******************************************************************************************************************* - function: count - - Author: Scott Severtson - *********************************************************************************************************************/ - - return this.m_arr.length; - -} // end function count - - -Stack.prototype.destroy = function() { - /******************************************************************************************************************* - function: destroy - - Author: Scott Severtson - *********************************************************************************************************************/ - - this.m_arr = null; - -} // end function destroy - - -Stack.prototype.peek = function() { - /******************************************************************************************************************* - function: peek - - Author: Scott Severtson - *********************************************************************************************************************/ - if(this.m_arr.length == 0) { - return null; - } - - return this.m_arr[this.m_arr.length - 1]; - -} // end function peek - - -Stack.prototype.pop = function() { - /******************************************************************************************************************* - function: pop - - Author: Scott Severtson - *********************************************************************************************************************/ - if(this.m_arr.length == 0) { - return null; - } - - var o = this.m_arr[this.m_arr.length - 1]; - this.m_arr.length--; - return o; - -} // end function pop - - -Stack.prototype.push = function(o) { - /******************************************************************************************************************* - function: push - - Author: Scott Severtson - *********************************************************************************************************************/ - - this.m_arr[this.m_arr.length] = o; - -} // end function push - - - -// ========================================================================= -// ========================================================================= -// ========================================================================= - -// CONVENIENCE FUNCTIONS - -// ========================================================================= -// ========================================================================= -// ========================================================================= - -function isEmpty(str) { - /******************************************************************************************************************* - function: isEmpty - - Author: mike@idle.org - - Description: - convenience function to identify an empty string - - *********************************************************************************************************************/ - return (str==null) || (str.length==0); - -} // end function isEmpty - - - -function trim(trimString, leftTrim, rightTrim) { - /******************************************************************************************************************* - function: trim - - Author: may106@psu.edu - - Description: - helper function to trip a string (trimString) of leading (leftTrim) - and trailing (rightTrim) whitespace - - *********************************************************************************************************************/ - if (isEmpty(trimString)) { - return ""; - } - - // the general focus here is on minimal method calls - hence only one - // substring is done to complete the trim. - - if (leftTrim == null) { - leftTrim = true; - } - - if (rightTrim == null) { - rightTrim = true; - } - - var left=0; - var right=0; - var i=0; - var k=0; - - - // modified to properly handle strings that are all whitespace - if (leftTrim == true) { - while ((i<trimString.length) && (whitespace.indexOf(trimString.charAt(i++))!=-1)) { - left++; - } - } - if (rightTrim == true) { - k=trimString.length-1; - while((k>=left) && (whitespace.indexOf(trimString.charAt(k--))!=-1)) { - right++; - } - } - return trimString.substring(left, trimString.length - right); -} // end function trim - -/** - * function __escapeString - * - * author: David Joham djoham@yahoo.com - * - * @param str : string - The string to be escaped - * - * @return : string - The escaped string - */ -function __escapeString(str) { - - var escAmpRegEx = /&/g; - var escLtRegEx = /</g; - var escGtRegEx = />/g; - var quotRegEx = /"/g; - var aposRegEx = /'/g; - - str = str.replace(escAmpRegEx, "&amp;"); - str = str.replace(escLtRegEx, "&lt;"); - str = str.replace(escGtRegEx, "&gt;"); - str = str.replace(quotRegEx, "&quot;"); - str = str.replace(aposRegEx, "&apos;"); - - return str; -} - -/** - * function __unescapeString - * - * author: David Joham djoham@yahoo.com - * - * @param str : string - The string to be unescaped - * - * @return : string - The unescaped string - */ -function __unescapeString(str) { - - var escAmpRegEx = /&amp;/g; - var escLtRegEx = /&lt;/g; - var escGtRegEx = /&gt;/g; - var quotRegEx = /&quot;/g; - var aposRegEx = /&apos;/g; - - str = str.replace(escAmpRegEx, "&"); - str = str.replace(escLtRegEx, "<"); - str = str.replace(escGtRegEx, ">"); - str = str.replace(quotRegEx, "\""); - str = str.replace(aposRegEx, "'"); - - return str; -} - +// ========================================================================= +// +// xmlsax.js - an XML SAX parser in JavaScript. +// +// version 3.1 +// +// ========================================================================= +// +// Copyright (C) 2001 - 2002 David Joham (djoham@yahoo.com) and Scott Severtson +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// +// Visit the XML for <SCRIPT> home page at http://xmljs.sourceforge.net +// + +// CONSTANTS + +// ========================================================================= +// ========================================================================= +// ========================================================================= +var whitespace = "\n\r\t "; + + +/*************************************************************************************************************** +XMLP is a pull-based parser. The calling application passes in a XML string +to the constructor, then repeatedly calls .next() to parse the next segment. +.next() returns a flag indicating what type of segment was found, and stores +data temporarily in couple member variables (name, content, array of +attributes), which can be accessed by several .get____() methods. + +Basically, XMLP is the lowest common denominator parser - an very simple +API which other wrappers can be built against. +*****************************************************************************************************************/ + + +XMLP = function(strXML) { + /******************************************************************************************************************* + function: this is the constructor to the XMLP Object + + Author: Scott Severtson + + Description: + Instantiates and initializes the object + *********************************************************************************************************************/ + // Normalize line breaks + strXML = SAXStrings.replace(strXML, null, null, "\r\n", "\n"); + strXML = SAXStrings.replace(strXML, null, null, "\r", "\n"); + + this.m_xml = strXML; + this.m_iP = 0; + this.m_iState = XMLP._STATE_PROLOG; + this.m_stack = new Stack(); + this._clearAttributes(); + +} // end XMLP constructor + + +// CONSTANTS (these must be below the constructor) + +// ========================================================================= +// ========================================================================= +// ========================================================================= + +XMLP._NONE = 0; +XMLP._ELM_B = 1; +XMLP._ELM_E = 2; +XMLP._ELM_EMP = 3; +XMLP._ATT = 4; +XMLP._TEXT = 5; +XMLP._ENTITY = 6; +XMLP._PI = 7; +XMLP._CDATA = 8; +XMLP._COMMENT = 9; +XMLP._DTD = 10; +XMLP._ERROR = 11; + +XMLP._CONT_XML = 0; +XMLP._CONT_ALT = 1; + +XMLP._ATT_NAME = 0; +XMLP._ATT_VAL = 1; + +XMLP._STATE_PROLOG = 1; +XMLP._STATE_DOCUMENT = 2; +XMLP._STATE_MISC = 3; + +XMLP._errs = new Array(); +XMLP._errs[XMLP.ERR_CLOSE_PI = 0 ] = "PI: missing closing sequence"; +XMLP._errs[XMLP.ERR_CLOSE_DTD = 1 ] = "DTD: missing closing sequence"; +XMLP._errs[XMLP.ERR_CLOSE_COMMENT = 2 ] = "Comment: missing closing sequence"; +XMLP._errs[XMLP.ERR_CLOSE_CDATA = 3 ] = "CDATA: missing closing sequence"; +XMLP._errs[XMLP.ERR_CLOSE_ELM = 4 ] = "Element: missing closing sequence"; +XMLP._errs[XMLP.ERR_CLOSE_ENTITY = 5 ] = "Entity: missing closing sequence"; +XMLP._errs[XMLP.ERR_PI_TARGET = 6 ] = "PI: target is required"; +XMLP._errs[XMLP.ERR_ELM_EMPTY = 7 ] = "Element: cannot be both empty and closing"; +XMLP._errs[XMLP.ERR_ELM_NAME = 8 ] = "Element: name must immediatly follow \"<\""; +XMLP._errs[XMLP.ERR_ELM_LT_NAME = 9 ] = "Element: \"<\" not allowed in element names"; +XMLP._errs[XMLP.ERR_ATT_VALUES = 10] = "Attribute: values are required and must be in quotes"; +XMLP._errs[XMLP.ERR_ATT_LT_NAME = 11] = "Element: \"<\" not allowed in attribute names"; +XMLP._errs[XMLP.ERR_ATT_LT_VALUE = 12] = "Attribute: \"<\" not allowed in attribute values"; +XMLP._errs[XMLP.ERR_ATT_DUP = 13] = "Attribute: duplicate attributes not allowed"; +XMLP._errs[XMLP.ERR_ENTITY_UNKNOWN = 14] = "Entity: unknown entity"; +XMLP._errs[XMLP.ERR_INFINITELOOP = 15] = "Infininte loop"; +XMLP._errs[XMLP.ERR_DOC_STRUCTURE = 16] = "Document: only comments, processing instructions, or whitespace allowed outside of document element"; +XMLP._errs[XMLP.ERR_ELM_NESTING = 17] = "Element: must be nested correctly"; + +// ========================================================================= +// ========================================================================= +// ========================================================================= + + +XMLP.prototype._addAttribute = function(name, value) { + /******************************************************************************************************************* + function: _addAttribute + + Author: Scott Severtson + *********************************************************************************************************************/ + this.m_atts[this.m_atts.length] = new Array(name, value); +} // end function _addAttribute + + +XMLP.prototype._checkStructure = function(iEvent) { + /******************************************************************************************************************* + function: _checkStructure + + Author: Scott Severtson + *********************************************************************************************************************/ + + if(XMLP._STATE_PROLOG == this.m_iState) { + if((XMLP._TEXT == iEvent) || (XMLP._ENTITY == iEvent)) { + if(SAXStrings.indexOfNonWhitespace(this.getContent(), this.getContentBegin(), this.getContentEnd()) != -1) { + return this._setErr(XMLP.ERR_DOC_STRUCTURE); + } + } + + if((XMLP._ELM_B == iEvent) || (XMLP._ELM_EMP == iEvent)) { + this.m_iState = XMLP._STATE_DOCUMENT; + // Don't return - fall through to next state + } + } + if(XMLP._STATE_DOCUMENT == this.m_iState) { + if((XMLP._ELM_B == iEvent) || (XMLP._ELM_EMP == iEvent)) { + this.m_stack.push(this.getName()); + } + + if((XMLP._ELM_E == iEvent) || (XMLP._ELM_EMP == iEvent)) { + var strTop = this.m_stack.pop(); + if((strTop == null) || (strTop != this.getName())) { + return this._setErr(XMLP.ERR_ELM_NESTING); + } + } + + if(this.m_stack.count() == 0) { + this.m_iState = XMLP._STATE_MISC; + return iEvent; + } + } + if(XMLP._STATE_MISC == this.m_iState) { + if((XMLP._ELM_B == iEvent) || (XMLP._ELM_E == iEvent) || (XMLP._ELM_EMP == iEvent) || (XMLP.EVT_DTD == iEvent)) { + return this._setErr(XMLP.ERR_DOC_STRUCTURE); + } + + if((XMLP._TEXT == iEvent) || (XMLP._ENTITY == iEvent)) { + if(SAXStrings.indexOfNonWhitespace(this.getContent(), this.getContentBegin(), this.getContentEnd()) != -1) { + return this._setErr(XMLP.ERR_DOC_STRUCTURE); + } + } + } + + return iEvent; + +} // end function _checkStructure + + +XMLP.prototype._clearAttributes = function() { + /******************************************************************************************************************* + function: _clearAttributes + + Author: Scott Severtson + *********************************************************************************************************************/ + this.m_atts = new Array(); +} // end function _clearAttributes + + +XMLP.prototype._findAttributeIndex = function(name) { + /******************************************************************************************************************* + function: findAttributeIndex + + Author: Scott Severtson + *********************************************************************************************************************/ + for(var i = 0; i < this.m_atts.length; i++) { + if(this.m_atts[i][XMLP._ATT_NAME] == name) { + return i; + } + } + return -1; + +} // end function _findAttributeIndex + + +XMLP.prototype.getAttributeCount = function() { + /******************************************************************************************************************* + function: getAttributeCount + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_atts ? this.m_atts.length : 0; + +} // end function getAttributeCount() + + +XMLP.prototype.getAttributeName = function(index) { + /******************************************************************************************************************* + function: getAttributeName + + Author: Scott Severtson + *********************************************************************************************************************/ + + return ((index < 0) || (index >= this.m_atts.length)) ? null : this.m_atts[index][XMLP._ATT_NAME]; + +} //end function getAttributeName + + +XMLP.prototype.getAttributeValue = function(index) { + /******************************************************************************************************************* + function: getAttributeValue + + Author: Scott Severtson + *********************************************************************************************************************/ + + return ((index < 0) || (index >= this.m_atts.length)) ? null : __unescapeString(this.m_atts[index][XMLP._ATT_VAL]); + +} // end function getAttributeValue + + +XMLP.prototype.getAttributeValueByName = function(name) { + /******************************************************************************************************************* + function: getAttributeValueByName + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.getAttributeValue(this._findAttributeIndex(name)); + +} // end function getAttributeValueByName + + +XMLP.prototype.getColumnNumber = function() { + /******************************************************************************************************************* + function: getColumnNumber + + Author: Scott Severtson + *********************************************************************************************************************/ + + return SAXStrings.getColumnNumber(this.m_xml, this.m_iP); + +} // end function getColumnNumber + + +XMLP.prototype.getContent = function() { + /******************************************************************************************************************* + function: getContent + + Author: Scott Severtson + *********************************************************************************************************************/ + + return (this.m_cSrc == XMLP._CONT_XML) ? this.m_xml : this.m_cAlt; + +} //end function getContent + + +XMLP.prototype.getContentBegin = function() { + /******************************************************************************************************************* + function: getContentBegin + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_cB; + +} //end function getContentBegin + + +XMLP.prototype.getContentEnd = function() { + /******************************************************************************************************************* + function: getContentEnd + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_cE; + +} // end function getContentEnd + + +XMLP.prototype.getLineNumber = function() { + /******************************************************************************************************************* + function: getLineNumber + + Author: Scott Severtson + *********************************************************************************************************************/ + + return SAXStrings.getLineNumber(this.m_xml, this.m_iP); + +} // end function getLineNumber + + +XMLP.prototype.getName = function() { + /******************************************************************************************************************* + function: getName + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_name; + +} // end function getName() + + +XMLP.prototype.next = function() { + /******************************************************************************************************************* + function: next + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this._checkStructure(this._parse()); + +} // end function next() + + +XMLP.prototype._parse = function() { + /******************************************************************************************************************* + function: _parse + + Author: Scott Severtson + *********************************************************************************************************************/ + + if(this.m_iP == this.m_xml.length) { + return XMLP._NONE; + } + + if(this.m_iP == this.m_xml.indexOf("<?", this.m_iP)) { + return this._parsePI (this.m_iP + 2); + } + else if(this.m_iP == this.m_xml.indexOf("<!DOCTYPE", this.m_iP)) { + return this._parseDTD (this.m_iP + 9); + } + else if(this.m_iP == this.m_xml.indexOf("<!--", this.m_iP)) { + return this._parseComment(this.m_iP + 4); + } + else if(this.m_iP == this.m_xml.indexOf("<![CDATA[", this.m_iP)) { + return this._parseCDATA (this.m_iP + 9); + } + else if(this.m_iP == this.m_xml.indexOf("<", this.m_iP)) { + return this._parseElement(this.m_iP + 1); + } + else if(this.m_iP == this.m_xml.indexOf("&", this.m_iP)) { + return this._parseEntity (this.m_iP + 1); + } + else{ + return this._parseText (this.m_iP); + } + + +} // end function _parse + + +XMLP.prototype._parseAttribute = function(iB, iE) { + /******************************************************************************************************************* + function: _parseAttribute + + Author: Scott Severtson + *********************************************************************************************************************/ + var iNB, iNE, iEq, iVB, iVE; + var cQuote, strN, strV; + + this.m_cAlt = ""; //resets the value so we don't use an old one by accident (see testAttribute7 in the test suite) + + iNB = SAXStrings.indexOfNonWhitespace(this.m_xml, iB, iE); + if((iNB == -1) ||(iNB >= iE)) { + return iNB; + } + + iEq = this.m_xml.indexOf("=", iNB); + if((iEq == -1) || (iEq > iE)) { + return this._setErr(XMLP.ERR_ATT_VALUES); + } + + iNE = SAXStrings.lastIndexOfNonWhitespace(this.m_xml, iNB, iEq); + + iVB = SAXStrings.indexOfNonWhitespace(this.m_xml, iEq + 1, iE); + if((iVB == -1) ||(iVB > iE)) { + return this._setErr(XMLP.ERR_ATT_VALUES); + } + + cQuote = this.m_xml.charAt(iVB); + if(SAXStrings.QUOTES.indexOf(cQuote) == -1) { + return this._setErr(XMLP.ERR_ATT_VALUES); + } + + iVE = this.m_xml.indexOf(cQuote, iVB + 1); + if((iVE == -1) ||(iVE > iE)) { + return this._setErr(XMLP.ERR_ATT_VALUES); + } + + strN = this.m_xml.substring(iNB, iNE + 1); + strV = this.m_xml.substring(iVB + 1, iVE); + + if(strN.indexOf("<") != -1) { + return this._setErr(XMLP.ERR_ATT_LT_NAME); + } + + if(strV.indexOf("<") != -1) { + return this._setErr(XMLP.ERR_ATT_LT_VALUE); + } + + strV = SAXStrings.replace(strV, null, null, "\n", " "); + strV = SAXStrings.replace(strV, null, null, "\t", " "); + iRet = this._replaceEntities(strV); + if(iRet == XMLP._ERROR) { + return iRet; + } + + strV = this.m_cAlt; + + if(this._findAttributeIndex(strN) == -1) { + this._addAttribute(strN, strV); + } + else { + return this._setErr(XMLP.ERR_ATT_DUP); + } + + this.m_iP = iVE + 2; + + return XMLP._ATT; + +} // end function _parseAttribute + + +XMLP.prototype._parseCDATA = function(iB) { + /******************************************************************************************************************* + function: _parseCDATA + + Author: Scott Severtson + *********************************************************************************************************************/ + var iE = this.m_xml.indexOf("]]>", iB); + if (iE == -1) { + return this._setErr(XMLP.ERR_CLOSE_CDATA); + } + + this._setContent(XMLP._CONT_XML, iB, iE); + + this.m_iP = iE + 3; + + return XMLP._CDATA; + +} // end function _parseCDATA + + +XMLP.prototype._parseComment = function(iB) { + /******************************************************************************************************************* + function: _parseComment + + Author: Scott Severtson + *********************************************************************************************************************/ + var iE = this.m_xml.indexOf("-" + "->", iB); + if (iE == -1) { + return this._setErr(XMLP.ERR_CLOSE_COMMENT); + } + + this._setContent(XMLP._CONT_XML, iB, iE); + + this.m_iP = iE + 3; + + return XMLP._COMMENT; + +} // end function _parseComment + + +XMLP.prototype._parseDTD = function(iB) { + /******************************************************************************************************************* + function: _parseDTD + + Author: Scott Severtson + *********************************************************************************************************************/ + + // Eat DTD + + var iE, strClose, iInt, iLast; + + iE = this.m_xml.indexOf(">", iB); + if(iE == -1) { + return this._setErr(XMLP.ERR_CLOSE_DTD); + } + + iInt = this.m_xml.indexOf("[", iB); + strClose = ((iInt != -1) && (iInt < iE)) ? "]>" : ">"; + + while(true) { + // DEBUG: Remove + if(iE == iLast) { + return this._setErr(XMLP.ERR_INFINITELOOP); + } + + iLast = iE; + // DEBUG: Remove End + + iE = this.m_xml.indexOf(strClose, iB); + if(iE == -1) { + return this._setErr(XMLP.ERR_CLOSE_DTD); + } + + // Make sure it is not the end of a CDATA section + if (this.m_xml.substring(iE - 1, iE + 2) != "]]>") { + break; + } + } + + this.m_iP = iE + strClose.length; + + return XMLP._DTD; + +} // end function _parseDTD + + +XMLP.prototype._parseElement = function(iB) { + /******************************************************************************************************************* + function: _parseElement + + Author: Scott Severtson + *********************************************************************************************************************/ + var iE, iDE, iNE, iRet; + var iType, strN, iLast; + + iDE = iE = this.m_xml.indexOf(">", iB); + if(iE == -1) { + return this._setErr(XMLP.ERR_CLOSE_ELM); + } + + if(this.m_xml.charAt(iB) == "/") { + iType = XMLP._ELM_E; + iB++; + } else { + iType = XMLP._ELM_B; + } + + if(this.m_xml.charAt(iE - 1) == "/") { + if(iType == XMLP._ELM_E) { + return this._setErr(XMLP.ERR_ELM_EMPTY); + } + iType = XMLP._ELM_EMP; + iDE--; + } + + iDE = SAXStrings.lastIndexOfNonWhitespace(this.m_xml, iB, iDE); + + //djohack + //hack to allow for elements with single character names to be recognized + + if (iE - iB != 1 ) { + if(SAXStrings.indexOfNonWhitespace(this.m_xml, iB, iDE) != iB) { + return this._setErr(XMLP.ERR_ELM_NAME); + } + } + // end hack -- original code below + + /* + if(SAXStrings.indexOfNonWhitespace(this.m_xml, iB, iDE) != iB) + return this._setErr(XMLP.ERR_ELM_NAME); + */ + this._clearAttributes(); + + iNE = SAXStrings.indexOfWhitespace(this.m_xml, iB, iDE); + if(iNE == -1) { + iNE = iDE + 1; + } + else { + this.m_iP = iNE; + while(this.m_iP < iDE) { + // DEBUG: Remove + if(this.m_iP == iLast) return this._setErr(XMLP.ERR_INFINITELOOP); + iLast = this.m_iP; + // DEBUG: Remove End + + + iRet = this._parseAttribute(this.m_iP, iDE); + if(iRet == XMLP._ERROR) return iRet; + } + } + + strN = this.m_xml.substring(iB, iNE); + + if(strN.indexOf("<") != -1) { + return this._setErr(XMLP.ERR_ELM_LT_NAME); + } + + this.m_name = strN; + this.m_iP = iE + 1; + + return iType; + +} // end function _parseElement + + +XMLP.prototype._parseEntity = function(iB) { + /******************************************************************************************************************* + function: _parseEntity + + Author: Scott Severtson + *********************************************************************************************************************/ + var iE = this.m_xml.indexOf(";", iB); + if(iE == -1) { + return this._setErr(XMLP.ERR_CLOSE_ENTITY); + } + + this.m_iP = iE + 1; + + return this._replaceEntity(this.m_xml, iB, iE); + +} // end function _parseEntity + + +XMLP.prototype._parsePI = function(iB) { + /******************************************************************************************************************* + function: _parsePI + + Author: Scott Severtson + *********************************************************************************************************************/ + + var iE, iTB, iTE, iCB, iCE; + + iE = this.m_xml.indexOf("?>", iB); + if(iE == -1) { + return this._setErr(XMLP.ERR_CLOSE_PI); + } + + iTB = SAXStrings.indexOfNonWhitespace(this.m_xml, iB, iE); + if(iTB == -1) { + return this._setErr(XMLP.ERR_PI_TARGET); + } + + iTE = SAXStrings.indexOfWhitespace(this.m_xml, iTB, iE); + if(iTE == -1) { + iTE = iE; + } + + iCB = SAXStrings.indexOfNonWhitespace(this.m_xml, iTE, iE); + if(iCB == -1) { + iCB = iE; + } + + iCE = SAXStrings.lastIndexOfNonWhitespace(this.m_xml, iCB, iE); + if(iCE == -1) { + iCE = iE - 1; + } + + this.m_name = this.m_xml.substring(iTB, iTE); + this._setContent(XMLP._CONT_XML, iCB, iCE + 1); + this.m_iP = iE + 2; + + return XMLP._PI; + +} // end function _parsePI + + +XMLP.prototype._parseText = function(iB) { + /******************************************************************************************************************* + function: _parseText + + Author: Scott Severtson + *********************************************************************************************************************/ + var iE, iEE; + + iE = this.m_xml.indexOf("<", iB); + if(iE == -1) { + iE = this.m_xml.length; + } + + iEE = this.m_xml.indexOf("&", iB); + if((iEE != -1) && (iEE <= iE)) { + iE = iEE; + } + + this._setContent(XMLP._CONT_XML, iB, iE); + + this.m_iP = iE; + + return XMLP._TEXT; + +} // end function _parseText + + +XMLP.prototype._replaceEntities = function(strD, iB, iE) { + /******************************************************************************************************************* + function: _replaceEntities + + Author: Scott Severtson + *********************************************************************************************************************/ + if(SAXStrings.isEmpty(strD)) return ""; + iB = iB || 0; + iE = iE || strD.length; + + + var iEB, iEE, strRet = ""; + + iEB = strD.indexOf("&", iB); + iEE = iB; + + while((iEB > 0) && (iEB < iE)) { + strRet += strD.substring(iEE, iEB); + + iEE = strD.indexOf(";", iEB) + 1; + + if((iEE == 0) || (iEE > iE)) { + return this._setErr(XMLP.ERR_CLOSE_ENTITY); + } + + iRet = this._replaceEntity(strD, iEB + 1, iEE - 1); + if(iRet == XMLP._ERROR) { + return iRet; + } + + strRet += this.m_cAlt; + + iEB = strD.indexOf("&", iEE); + } + + if(iEE != iE) { + strRet += strD.substring(iEE, iE); + } + + this._setContent(XMLP._CONT_ALT, strRet); + + return XMLP._ENTITY; + +} // end function _replaceEntities + + +XMLP.prototype._replaceEntity = function(strD, iB, iE) { + /******************************************************************************************************************* + function: _replaceEntity + + Author: Scott Severtson + *********************************************************************************************************************/ + if(SAXStrings.isEmpty(strD)) return -1; + iB = iB || 0; + iE = iE || strD.length; + + switch(strD.substring(iB, iE)) { + case "amp": strEnt = "&"; break; + case "lt": strEnt = "<"; break; + case "gt": strEnt = ">"; break; + case "apos": strEnt = "'"; break; + case "quot": strEnt = "\""; break; + default: + if(strD.charAt(iB) == "#") { + strEnt = String.fromCharCode(parseInt(strD.substring(iB + 1, iE))); + } else { + return this._setErr(XMLP.ERR_ENTITY_UNKNOWN); + } + break; + } + this._setContent(XMLP._CONT_ALT, strEnt); + + return XMLP._ENTITY; +} // end function _replaceEntity + + +XMLP.prototype._setContent = function(iSrc) { + /******************************************************************************************************************* + function: _setContent + + Author: Scott Severtson + *********************************************************************************************************************/ + var args = arguments; + + if(XMLP._CONT_XML == iSrc) { + this.m_cAlt = null; + this.m_cB = args[1]; + this.m_cE = args[2]; + } else { + this.m_cAlt = args[1]; + this.m_cB = 0; + this.m_cE = args[1].length; + } + this.m_cSrc = iSrc; + +} // end function _setContent + + +XMLP.prototype._setErr = function(iErr) { + /******************************************************************************************************************* + function: _setErr + + Author: Scott Severtson + *********************************************************************************************************************/ + var strErr = XMLP._errs[iErr]; + + this.m_cAlt = strErr; + this.m_cB = 0; + this.m_cE = strErr.length; + this.m_cSrc = XMLP._CONT_ALT; + + return XMLP._ERROR; + +} // end function _setErr + + + + + + +/*************************************************************************************************************** +SAXDriver is an object that basically wraps an XMLP instance, and provides an +event-based interface for parsing. This is the object users interact with when coding +with XML for <SCRIPT> +*****************************************************************************************************************/ + + +SAXDriver = function() { + /******************************************************************************************************************* + function: SAXDriver + + Author: Scott Severtson + + Description: + This is the constructor for the SAXDriver Object + *********************************************************************************************************************/ + this.m_hndDoc = null; + this.m_hndErr = null; + this.m_hndLex = null; +} + + +// CONSTANTS (these must be below the constructor) + +// ========================================================================= +// ========================================================================= +// ========================================================================= +SAXDriver.DOC_B = 1; +SAXDriver.DOC_E = 2; +SAXDriver.ELM_B = 3; +SAXDriver.ELM_E = 4; +SAXDriver.CHARS = 5; +SAXDriver.PI = 6; +SAXDriver.CD_B = 7; +SAXDriver.CD_E = 8; +SAXDriver.CMNT = 9; +SAXDriver.DTD_B = 10; +SAXDriver.DTD_E = 11; +// ========================================================================= +// ========================================================================= +// ========================================================================= + + + +SAXDriver.prototype.parse = function(strD) { + /******************************************************************************************************************* + function: parse + + Author: Scott Severtson + *********************************************************************************************************************/ + var parser = new XMLP(strD); + + if(this.m_hndDoc && this.m_hndDoc.setDocumentLocator) { + this.m_hndDoc.setDocumentLocator(this); + } + + this.m_parser = parser; + this.m_bErr = false; + + if(!this.m_bErr) { + this._fireEvent(SAXDriver.DOC_B); + } + this._parseLoop(); + if(!this.m_bErr) { + this._fireEvent(SAXDriver.DOC_E); + } + + this.m_xml = null; + this.m_iP = 0; + +} // end function parse + + +SAXDriver.prototype.setDocumentHandler = function(hnd) { + /******************************************************************************************************************* + function: setDocumentHandler + + Author: Scott Severtson + *********************************************************************************************************************/ + + this.m_hndDoc = hnd; + +} // end function setDocumentHandler + + +SAXDriver.prototype.setErrorHandler = function(hnd) { + /******************************************************************************************************************* + function: setErrorHandler + + Author: Scott Severtson + *********************************************************************************************************************/ + + this.m_hndErr = hnd; + +} // end function setErrorHandler + + +SAXDriver.prototype.setLexicalHandler = function(hnd) { + /******************************************************************************************************************* + function: setLexicalHandler + + Author: Scott Severtson + *********************************************************************************************************************/ + + this.m_hndLex = hnd; + +} // end function setLexicalHandler + + + /******************************************************************************************************************* + LOCATOR/PARSE EXCEPTION INTERFACE + *********************************************************************************************************************/ + +SAXDriver.prototype.getColumnNumber = function() { + /******************************************************************************************************************* + function: getSystemId + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_parser.getColumnNumber(); + +} // end function getColumnNumber + + +SAXDriver.prototype.getLineNumber = function() { + /******************************************************************************************************************* + function: getLineNumber + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_parser.getLineNumber(); + +} // end function getLineNumber + + +SAXDriver.prototype.getMessage = function() { + /******************************************************************************************************************* + function: getMessage + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_strErrMsg; + +} // end function getMessage + + +SAXDriver.prototype.getPublicId = function() { + /******************************************************************************************************************* + function: getPublicID + + Author: Scott Severtson + *********************************************************************************************************************/ + + return null; + +} // end function getPublicID + + +SAXDriver.prototype.getSystemId = function() { + /******************************************************************************************************************* + function: getSystemId + + Author: Scott Severtson + *********************************************************************************************************************/ + + return null; + +} // end function getSystemId + + + /******************************************************************************************************************* + Attribute List Interface + *********************************************************************************************************************/ + +SAXDriver.prototype.getLength = function() { + /******************************************************************************************************************* + function: getLength + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_parser.getAttributeCount(); + +} // end function getAttributeCount + + +SAXDriver.prototype.getName = function(index) { + /******************************************************************************************************************* + function: getName + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_parser.getAttributeName(index); + +} // end function getAttributeName + + +SAXDriver.prototype.getValue = function(index) { + /******************************************************************************************************************* + function: getValue + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_parser.getAttributeValue(index); + +} // end function getAttributeValue + + +SAXDriver.prototype.getValueByName = function(name) { + /******************************************************************************************************************* + function: getValueByName + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_parser.getAttributeValueByName(name); + +} // end function getAttributeValueByName + + + /******************************************************************************************************************* + Private functions + *********************************************************************************************************************/ + +SAXDriver.prototype._fireError = function(strMsg) { + /******************************************************************************************************************* + function: _fireError + + Author: Scott Severtson + *********************************************************************************************************************/ + this.m_strErrMsg = strMsg; + this.m_bErr = true; + + if(this.m_hndErr && this.m_hndErr.fatalError) { + this.m_hndErr.fatalError(this); + } + +} // end function _fireError + + +SAXDriver.prototype._fireEvent = function(iEvt) { + /******************************************************************************************************************* + function: _fireEvent + + Author: Scott Severtson + *********************************************************************************************************************/ + var hnd, func, args = arguments, iLen = args.length - 1; + + if(this.m_bErr) return; + + if(SAXDriver.DOC_B == iEvt) { + func = "startDocument"; hnd = this.m_hndDoc; + } + else if (SAXDriver.DOC_E == iEvt) { + func = "endDocument"; hnd = this.m_hndDoc; + } + else if (SAXDriver.ELM_B == iEvt) { + func = "startElement"; hnd = this.m_hndDoc; + } + else if (SAXDriver.ELM_E == iEvt) { + func = "endElement"; hnd = this.m_hndDoc; + } + else if (SAXDriver.CHARS == iEvt) { + func = "characters"; hnd = this.m_hndDoc; + } + else if (SAXDriver.PI == iEvt) { + func = "processingInstruction"; hnd = this.m_hndDoc; + } + else if (SAXDriver.CD_B == iEvt) { + func = "startCDATA"; hnd = this.m_hndLex; + } + else if (SAXDriver.CD_E == iEvt) { + func = "endCDATA"; hnd = this.m_hndLex; + } + else if (SAXDriver.CMNT == iEvt) { + func = "comment"; hnd = this.m_hndLex; + } + + if(hnd && hnd[func]) { + if(0 == iLen) { + hnd[func](); + } + else if (1 == iLen) { + hnd[func](args[1]); + } + else if (2 == iLen) { + hnd[func](args[1], args[2]); + } + else if (3 == iLen) { + hnd[func](args[1], args[2], args[3]); + } + } + +} // end function _fireEvent + + +SAXDriver.prototype._parseLoop = function(parser) { + /******************************************************************************************************************* + function: _parseLoop + + Author: Scott Severtson + *********************************************************************************************************************/ + var iEvent, parser; + + parser = this.m_parser; + while(!this.m_bErr) { + iEvent = parser.next(); + + if(iEvent == XMLP._ELM_B) { + this._fireEvent(SAXDriver.ELM_B, parser.getName(), this); + } + else if(iEvent == XMLP._ELM_E) { + this._fireEvent(SAXDriver.ELM_E, parser.getName()); + } + else if(iEvent == XMLP._ELM_EMP) { + this._fireEvent(SAXDriver.ELM_B, parser.getName(), this); + this._fireEvent(SAXDriver.ELM_E, parser.getName()); + } + else if(iEvent == XMLP._TEXT) { + this._fireEvent(SAXDriver.CHARS, parser.getContent(), parser.getContentBegin(), parser.getContentEnd() - parser.getContentBegin()); + } + else if(iEvent == XMLP._ENTITY) { + this._fireEvent(SAXDriver.CHARS, parser.getContent(), parser.getContentBegin(), parser.getContentEnd() - parser.getContentBegin()); + } + else if(iEvent == XMLP._PI) { + this._fireEvent(SAXDriver.PI, parser.getName(), parser.getContent().substring(parser.getContentBegin(), parser.getContentEnd())); + } + else if(iEvent == XMLP._CDATA) { + this._fireEvent(SAXDriver.CD_B); + this._fireEvent(SAXDriver.CHARS, parser.getContent(), parser.getContentBegin(), parser.getContentEnd() - parser.getContentBegin()); + this._fireEvent(SAXDriver.CD_E); + } + else if(iEvent == XMLP._COMMENT) { + this._fireEvent(SAXDriver.CMNT, parser.getContent(), parser.getContentBegin(), parser.getContentEnd() - parser.getContentBegin()); + } + else if(iEvent == XMLP._DTD) { + } + else if(iEvent == XMLP._ERROR) { + this._fireError(parser.getContent()); + } + else if(iEvent == XMLP._NONE) { + return; + } + } + +} // end function _parseLoop + + + +/*************************************************************************************************************** +SAXStrings: a useful object containing string manipulation functions +*****************************************************************************************************************/ + + +SAXStrings = function() { + /******************************************************************************************************************* + function: SAXStrings + + Author: Scott Severtson + + Description: + This is the constructor of the SAXStrings object + *********************************************************************************************************************/ +} // end function SAXStrings + + +// CONSTANTS (these must be below the constructor) + +// ========================================================================= +// ========================================================================= +// ========================================================================= +SAXStrings.WHITESPACE = " \t\n\r"; +SAXStrings.QUOTES = "\"'"; +// ========================================================================= +// ========================================================================= +// ========================================================================= + + +SAXStrings.getColumnNumber = function(strD, iP) { + /******************************************************************************************************************* + function: replace + + Author: Scott Severtson + *********************************************************************************************************************/ + if(SAXStrings.isEmpty(strD)) { + return -1; + } + iP = iP || strD.length; + + var arrD = strD.substring(0, iP).split("\n"); + var strLine = arrD[arrD.length - 1]; + arrD.length--; + var iLinePos = arrD.join("\n").length; + + return iP - iLinePos; + +} // end function getColumnNumber + + +SAXStrings.getLineNumber = function(strD, iP) { + /******************************************************************************************************************* + function: getLineNumber + + Author: Scott Severtson + *********************************************************************************************************************/ + if(SAXStrings.isEmpty(strD)) { + return -1; + } + iP = iP || strD.length; + + return strD.substring(0, iP).split("\n").length +} // end function getLineNumber + + +SAXStrings.indexOfNonWhitespace = function(strD, iB, iE) { + /******************************************************************************************************************* + function: indexOfNonWhitespace + + Author: Scott Severtson + *********************************************************************************************************************/ + if(SAXStrings.isEmpty(strD)) { + return -1; + } + iB = iB || 0; + iE = iE || strD.length; + + for(var i = iB; i < iE; i++){ + if(SAXStrings.WHITESPACE.indexOf(strD.charAt(i)) == -1) { + return i; + } + } + return -1; + +} // end function indexOfNonWhitespace + + +SAXStrings.indexOfWhitespace = function(strD, iB, iE) { + /******************************************************************************************************************* + function: indexOfWhitespace + + Author: Scott Severtson + *********************************************************************************************************************/ + if(SAXStrings.isEmpty(strD)) { + return -1; + } + iB = iB || 0; + iE = iE || strD.length; + + for(var i = iB; i < iE; i++) { + if(SAXStrings.WHITESPACE.indexOf(strD.charAt(i)) != -1) { + return i; + } + } + return -1; +} // end function indexOfWhitespace + + +SAXStrings.isEmpty = function(strD) { + /******************************************************************************************************************* + function: isEmpty + + Author: Scott Severtson + *********************************************************************************************************************/ + + return (strD == null) || (strD.length == 0); + +} // end function isEmpty + + +SAXStrings.lastIndexOfNonWhitespace = function(strD, iB, iE) { + /******************************************************************************************************************* + function: lastIndexOfNonWhiteSpace + + Author: Scott Severtson + *********************************************************************************************************************/ + if(SAXStrings.isEmpty(strD)) { + return -1; + } + iB = iB || 0; + iE = iE || strD.length; + + for(var i = iE - 1; i >= iB; i--){ + if(SAXStrings.WHITESPACE.indexOf(strD.charAt(i)) == -1){ + return i; + } + } + return -1; +} // end function lastIndexOfNonWhitespace + + +SAXStrings.replace = function(strD, iB, iE, strF, strR) { + /******************************************************************************************************************* + function: replace + + Author: Scott Severtson + *********************************************************************************************************************/ + if(SAXStrings.isEmpty(strD)) { + return ""; + } + iB = iB || 0; + iE = iE || strD.length; + + return strD.substring(iB, iE).split(strF).join(strR); + +} // end function replace + + + +/*************************************************************************************************************** +Stack: A simple stack class, used for verifying document structure. +*****************************************************************************************************************/ + +Stack = function() { + /******************************************************************************************************************* + function: Stack + + Author: Scott Severtson + + Description: + Constructor of the Stack Object + *********************************************************************************************************************/ + this.m_arr = new Array(); + +} // end function Stack + + +Stack.prototype.clear = function() { + /******************************************************************************************************************* + function: clear + + Author: Scott Severtson + *********************************************************************************************************************/ + + this.m_arr = new Array(); + +} // end function clear + + +Stack.prototype.count = function() { + /******************************************************************************************************************* + function: count + + Author: Scott Severtson + *********************************************************************************************************************/ + + return this.m_arr.length; + +} // end function count + + +Stack.prototype.destroy = function() { + /******************************************************************************************************************* + function: destroy + + Author: Scott Severtson + *********************************************************************************************************************/ + + this.m_arr = null; + +} // end function destroy + + +Stack.prototype.peek = function() { + /******************************************************************************************************************* + function: peek + + Author: Scott Severtson + *********************************************************************************************************************/ + if(this.m_arr.length == 0) { + return null; + } + + return this.m_arr[this.m_arr.length - 1]; + +} // end function peek + + +Stack.prototype.pop = function() { + /******************************************************************************************************************* + function: pop + + Author: Scott Severtson + *********************************************************************************************************************/ + if(this.m_arr.length == 0) { + return null; + } + + var o = this.m_arr[this.m_arr.length - 1]; + this.m_arr.length--; + return o; + +} // end function pop + + +Stack.prototype.push = function(o) { + /******************************************************************************************************************* + function: push + + Author: Scott Severtson + *********************************************************************************************************************/ + + this.m_arr[this.m_arr.length] = o; + +} // end function push + + + +// ========================================================================= +// ========================================================================= +// ========================================================================= + +// CONVENIENCE FUNCTIONS + +// ========================================================================= +// ========================================================================= +// ========================================================================= + +function isEmpty(str) { + /******************************************************************************************************************* + function: isEmpty + + Author: mike@idle.org + + Description: + convenience function to identify an empty string + + *********************************************************************************************************************/ + return (str==null) || (str.length==0); + +} // end function isEmpty + + + +function trim(trimString, leftTrim, rightTrim) { + /******************************************************************************************************************* + function: trim + + Author: may106@psu.edu + + Description: + helper function to trip a string (trimString) of leading (leftTrim) + and trailing (rightTrim) whitespace + + *********************************************************************************************************************/ + if (isEmpty(trimString)) { + return ""; + } + + // the general focus here is on minimal method calls - hence only one + // substring is done to complete the trim. + + if (leftTrim == null) { + leftTrim = true; + } + + if (rightTrim == null) { + rightTrim = true; + } + + var left=0; + var right=0; + var i=0; + var k=0; + + + // modified to properly handle strings that are all whitespace + if (leftTrim == true) { + while ((i<trimString.length) && (whitespace.indexOf(trimString.charAt(i++))!=-1)) { + left++; + } + } + if (rightTrim == true) { + k=trimString.length-1; + while((k>=left) && (whitespace.indexOf(trimString.charAt(k--))!=-1)) { + right++; + } + } + return trimString.substring(left, trimString.length - right); +} // end function trim + +/** + * function __escapeString + * + * author: David Joham djoham@yahoo.com + * + * @param str : string - The string to be escaped + * + * @return : string - The escaped string + */ +function __escapeString(str) { + + var escAmpRegEx = /&/g; + var escLtRegEx = /</g; + var escGtRegEx = />/g; + var quotRegEx = /"/g; + var aposRegEx = /'/g; + + str = str.replace(escAmpRegEx, "&amp;"); + str = str.replace(escLtRegEx, "&lt;"); + str = str.replace(escGtRegEx, "&gt;"); + str = str.replace(quotRegEx, "&quot;"); + str = str.replace(aposRegEx, "&apos;"); + + return str; +} + +/** + * function __unescapeString + * + * author: David Joham djoham@yahoo.com + * + * @param str : string - The string to be unescaped + * + * @return : string - The unescaped string + */ +function __unescapeString(str) { + + var escAmpRegEx = /&amp;/g; + var escLtRegEx = /&lt;/g; + var escGtRegEx = /&gt;/g; + var quotRegEx = /&quot;/g; + var aposRegEx = /&apos;/g; + + str = str.replace(escAmpRegEx, "&"); + str = str.replace(escLtRegEx, "<"); + str = str.replace(escGtRegEx, ">"); + str = str.replace(quotRegEx, "\""); + str = str.replace(aposRegEx, "'"); + + return str; +} +