} // /** * returns false in case of error. closedTag returns true if the node is self-terminating: <node /> */ private bool ReadStartTag(XMLNode node, ref bool closedTag) { if (!MatchChar(START_NODE)) { this.error = true; return(false); } string nodeName = this.ReadIdentifier(); if (this.error || nodeName == String.Empty) { return(false); } node.NodeName = nodeName; Char next = this.GetNextNonWhite(); // READ ATTRIBUTES UNTIL THEY RUN OUT. while (Char.IsLetter(next)) { // backtrack to the character. this.curIndex--; if (!this.ReadAttribute(node)) { this.error = true; return(false); } next = this.GetNextNonWhite(); } // // READ END TAG. if (next == SLASH) { next = this.GetNextNonWhite(); if (next == END_NODE) { closedTag = true; return(true); } } else if (next == END_NODE) { closedTag = false; return(true); } return(false); } //
} // public void AddNode(XMLNode node) { if (this._first == null) { this._first = this._last = node; } else { node.Prev = this._last; node.Next = null; node.Prev.Next = node; this._last = node; } // } // addChild()
} // public XMLNode Parse(string plainText) { this.error = false; this.curIndex = 0; this.text = plainText; XMLNode node = this.ReadXMLNode(); if (node == null) { return(null); } return(node); } //
} // /** * attempts to read a name="value" attribute, and returns false * if parsing fails. */ private Boolean ReadAttribute(XMLNode node) { string attr = this.ReadIdentifier(); MatchChar(EQUAL_SIGN); MatchChar(QUOTE_MARK); string value = this.ReadText(QUOTE_MARK); MatchChar(QUOTE_MARK); // assign the attribute in the xml node. node[attr] = value; return(true); } //
} // /** * read an xml node that has an opening tag. */ private XMLNode ReadXMLNode() { bool closedTag = false; XMLNode node = new XMLNode(); if (!ReadStartTag(node, ref closedTag)) { // error return(null); } if (closedTag) { // node was self-contained: <node /> return(node); } // if the node turns out to be a text node, need to return to this index // because any white space will be part of the text. int saveIndex = curIndex; Char next = this.GetNextNonWhite(); XMLNode child; if (next == START_NODE) { do { next = this.GetNextNonWhite(); // backtrack so the '<' and what follows can be read by further parsing. this.curIndex = saveIndex; if (next == SLASH) { // found the start of an end node: "</" // this has to be the end tag for this node, or there is an error. break; } // child = this.ReadXMLNode(); if (child == null) { return(null); } node.AddChild(child); // save position to return to the spot right before the '<' tag. saveIndex = this.curIndex; // get what should be the next '<' tag. next = this.GetNextNonWhite(); } while (next == START_NODE); } else { // assume the node is text. attempt to parse text. this.curIndex = saveIndex; if (!this.ReadNodeText(node)) { return(null); } } // if (!ReadEndTag(node)) { return(null); } return(node); } //
} // public XMLList() { this._first = null; this._last = null; } //