/// <summary> /// Push element onto stack /// </summary> /// <param name="e"></param> private void Push(Element e) { string name = e.Name; string localName = e.LocalName; string ns = e.Namespace; string prefix = PrefixOf(name); // System.err.println("%% Pushing " + name); e.Clean(); if (!_namespaces) { ns = localName = ""; } if (_virginStack && localName.Equals(_doctypeName, StringComparison.OrdinalIgnoreCase)) { try { _entityResolver.ResolveEntity(_doctypePublicId, _doctypeSystemId); } catch (IOException ew) { } // Can't be thrown for root I believe. } if (Foreign(prefix, ns)) { _contentHandler.StartPrefixMapping(prefix, ns); // System.err.println("%% Mapping [" + prefix + "] for elements to " + namespace); } Attributes atts = e.Attributes; int len = atts.Length; for (int i = 0; i < len; i++) { string attNamespace = atts.GetUri(i); string attPrefix = PrefixOf(atts.GetQName(i)); if (Foreign(attPrefix, attNamespace)) { _contentHandler.StartPrefixMapping(attPrefix, attNamespace); // System.err.println("%% Mapping [" + attPrefix + "] for attributes to " + attNamespace); } } _contentHandler.StartElement(ns, localName, name, e.Attributes); e.Next = _stack; _stack = e; _virginStack = false; if (_cdataElements && (_stack.Flags & Schema.F_CDATA) != 0) { _scanner.StartCDATA(); } }
/// <summary> /// Pop the stack irrevocably /// </summary> private void Pop() { if (_stack == null) { return; // empty stack } string name = _stack.Name; string localName = _stack.LocalName; string ns = _stack.Namespace; string prefix = PrefixOf(name); // System.err.println("%% Popping " + name); if (!_namespaces) { ns = localName = ""; } _contentHandler.EndElement(ns, localName, name); if (Foreign(prefix, ns)) { _contentHandler.EndPrefixMapping(prefix); // System.err.println("%% Unmapping [" + prefix + "] for elements to " + namespace); } Attributes atts = _stack.Attributes; for (int i = atts.Length - 1; i >= 0; i--) { string attNamespace = atts.GetUri(i); string attPrefix = PrefixOf(atts.GetQName(i)); if (Foreign(attPrefix, attNamespace)) { _contentHandler.EndPrefixMapping(attPrefix); // System.err.println("%% Unmapping [" + attPrefix + "] for attributes to " + attNamespace); } } _stack = _stack.Next; }
/// <summary> /// Pop the stack restartably /// </summary> private void RestartablyPop() { Element popped = _stack; Pop(); if (_restartElements && (popped.Flags & Schema.F_RESTART) != 0) { popped.Anonymize(); popped.Next = _saved; _saved = popped; } }
public void ETagBasic(char[] buff, int offset, int length) { _newElement = null; string name; if (length != 0) { // Canonicalize case of name name = MakeName(buff, offset, length); // System.err.println("got etag [" + name + "]"); ElementType type = _schema.GetElementType(name); if (type == null) { return; // mysterious end-tag } name = type.Name; } else { name = _stack.Name; } // System.err.println("%% Got end of " + name); Element sp; bool inNoforce = false; for (sp = _stack; sp != null; sp = sp.Next) { if (sp.Name.Equals(name)) { break; } if ((sp.Flags & Schema.F_NOFORCE) != 0) { inNoforce = true; } } if (sp == null) { return; // Ignore unknown etags } if (sp.Next == null || sp.Next.Next == null) { return; } if (inNoforce) { // inside an F_NOFORCE element? sp.Preclose(); // preclose the matching element } else { // restartably pop everything above us while (_stack != sp) { RestartablyPop(); } Pop(); } // pop any preclosed elements now at the top while (_stack.IsPreclosed) { Pop(); } Restart(null); }
/// <summary> /// Push restartables on the stack if possible /// e is the next element to be started, if we know what it is /// </summary> /// <param name="e"></param> private void Restart(Element e) { while (_saved != null && _stack.CanContain(_saved) && (e == null || _saved.CanContain(e))) { Element next = _saved.Next; Push(_saved); _saved = next; } }
// Sets up instance variables that haven't been set by setFeature private void Setup() { if (_schema == null) { _schema = new HTMLSchema(); } if (_scanner == null) { _scanner = new HTMLScanner(); } if (_autoDetector == null) { _autoDetector = new AutoDetectorDelegate(stream => new StreamReader(stream)); } _stack = new Element(_schema.GetElementType("<root>"), _defaultAttributes); _pcdata = new Element(_schema.GetElementType("<pcdata>"), _defaultAttributes); _newElement = null; _attributeName = null; _piTarget = null; _saved = null; _entity = 0; _virginStack = true; _doctypeName = _doctypePublicId = _doctypeSystemId = null; }
public void GI(char[] buff, int offset, int length) { if (_newElement != null) { return; } string name = MakeName(buff, offset, length); if (name == null) { return; } ElementType type = _schema.GetElementType(name); if (type == null) { // Suppress unknown elements if ignore-bogons is on if (_ignoreBogons) { return; } int bogonModel = (_bogonsEmpty ? Schema.M_EMPTY : Schema.M_ANY); int bogonMemberOf = (_rootBogons ? Schema.M_ANY : (Schema.M_ANY & ~ Schema.M_ROOT)); _schema.ElementType(name, bogonModel, bogonMemberOf, 0); if (!_rootBogons) { _schema.Parent(name, _schema.RootElementType.Name); } type = _schema.GetElementType(name); } _newElement = new Element(type, _defaultAttributes); // System.err.println("%% Got GI " + theNewElement.name()); }
/// <summary> /// Creates a new instance of <see cref="Parser" /> /// </summary> public Parser() { _newElement = null; _contentHandler = this; _lexicalHandler = this; _dtdHandler = this; _errorHandler = this; _entityResolver = this; }
/// <summary> /// Rectify the stack, pushing and popping as needed /// so that the argument can be safely pushed /// </summary> /// <param name="e"></param> private void Rectify(Element e) { Element sp; while (true) { for (sp = _stack; sp != null; sp = sp.Next) { if (sp.CanContain(e)) { break; } } if (sp != null) { break; } ElementType parentType = e.Parent; if (parentType == null) { break; } var parent = new Element(parentType, _defaultAttributes); // System.err.println("%% Ascending from " + e.name() + " to " + parent.name()); parent.Next = e; e = parent; } if (sp == null) { return; // don't know what to do } while (_stack != sp) { if (_stack == null || _stack.Next == null || _stack.Next.Next == null) { break; } RestartablyPop(); } while (e != null) { Element nexte = e.Next; if (!e.Name.Equals("<pcdata>")) { Push(e); } e = nexte; Restart(e); } _newElement = null; }
/// <summary> /// Return true if the type of this element can contain the type of /// another element. /// Convenience method. /// </summary> /// <param name="other"> /// The other element /// </param> public bool CanContain(Element other) { return _type.CanContain(other._type); }