Ejemplo n.º 1
0
 public void CopyAttributes( Node n )
 {
     var len = n._attributes.Count;
       for( var i = 0; i < len; i++ ) {
     var a = (Attribute) n._attributes[ i ];
     var na = AddAttribute( a.Name, a.Value, a.QuoteChar, false );
     na.DtdType = a.DtdType;
       }
 }
Ejemplo n.º 2
0
        private void ValidateContent( Node node )
        {
            if( node.NodeType == XmlNodeType.Element ) {
            if( !VerifyName( node.Name ) ) {
              Pop();
              Push( null, XmlNodeType.Text, "<" + node.Name + ">" );
              return;
            }
              }

              if( _dtd == null ) return;

              // See if this element is allowed inside the current element.
              // If it isn't, then auto-close elements until we find one
              // that it is allowed to be in.
              var name = node.Name.ToUpperInvariant(); // DTD is in upper case
              var i = 0;
              var top = _stack.Count - 2;
              if( node.DtdType != null ) {
            // it is a known element, let's see if it's allowed in the
            // current context.
            for( i = top; i > 0; i-- ) {
              var n = (Node) _stack[ i ];
              if( n.IsEmpty )
            continue; // we'll have to pop this one
              var f = n.DtdType;
              if(
            // Since we don't understand this tag anyway,
            // we might as well allow this content!
            f == null ||
            // NOTE (steveb): never close the BODY tag too early
            ( i == 2 && f.Name.EqualsIgnoreCase( "BODY" ) ) ||
            // can't pop the root element.
            f.Name.EqualsIgnoreCase( _dtd.Name ) ||
            f.CanContain( name, _dtd ) ||
            // If the end tag is not optional then we can't
            // auto-close it.  We'll just have to live with the
            // junk we've found and move on.
            !f.EndTagOptional
              ) break;
            }
              }

              if( i == 0 ) {
            // Tag was not found or is not allowed anywhere, ignore it and
            // continue on.
            return;
              }

              if( i >= top ) return;
              var t = (Node) _stack[ top ];
              if( i == top - 1 && name.EqualsIgnoreCase( t.Name ) ) {
            // e.g. p not allowed inside p, not an interesting error.
              }
              else {
            #if DEBUG
            var closing = "";
            for( var k = top; k >= i + 1; k-- ) {
              if( closing != "" ) closing += ",";
              var n2 = (Node) _stack[ k ];
              closing += "<" + n2.Name + ">";
            }
            Log( "Element '{0}' not allowed inside '{1}', closing {2}.", name, t.Name, closing );
            #endif
              }

              _state = State.AutoClose;
              _newNode = node;
              Pop(); // save this new node until we pop the others
              _popToDepth = i + 1;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Reads the next node from the stream.
        /// </summary>
        /// <returns>true if the next node was read successfully; false if there are no more nodes to read.</returns>
        public override bool Read()
        {
            if( _current == null ) {
            OpenInput();
              }

              if( _node.Simulated ) {
            // return the next node
            _node.Simulated = false;
            _node = Top();
            _state = _node.CurrentState;
            return true;
              }

              var foundnode = false;
              while( !foundnode ) {
            switch( _state ) {
              case State.Initial:
            _state = State.Markup;
            _current.ReadChar();
            goto case State.Markup;
              case State.Eof:
            if( _current.Parent != null ) {
              _current.Close();
              _current = _current.Parent;
            }
            else {
              return false;
            }
            break;
              case State.EndTag:
            if( _endTag.EqualsIgnoreCase( _node.Name ) ) {
              Pop(); // we're done!
              _state = State.Markup;
              goto case State.Markup;
            }
            Pop(); // close one element
            foundnode = true;// return another end element.
            break;
              case State.Markup:
            if( _node.IsEmpty ) {
              Pop();
            }
            foundnode = ParseMarkup();
            break;
              case State.PartialTag:
            Pop(); // remove text node.
            _state = State.Markup;
            foundnode = ParseTag( _partial );
            break;
              case State.PseudoStartTag:
            foundnode = ParseStartTag( '<' );
            break;
              case State.AutoClose:
            Pop(); // close next node.
            if( _stack.Count <= _popToDepth ) {
              _state = State.Markup;
              if( _newNode != null ) {
                Push( _newNode ); // now we're ready to start the new node.
                _newNode = null;
                _state = State.Markup;
              }
              else if( _node.NodeType == XmlNodeType.Document ) {
                _state = State.Eof;
                goto case State.Eof;
              }
            }
            foundnode = true;
            break;
              case State.CData:
            foundnode = ParseCData();
            break;
              case State.Attr:
            goto case State.AttrValue;
              case State.AttrValue:
            _state = State.Markup;
            goto case State.Markup;
              case State.Text:
            Pop();
            goto case State.Markup;
              case State.PartialText:
            if( ParseText( _current.Lastchar, false ) ) {
              _node.NodeType = XmlNodeType.Whitespace;
            }

            foundnode = true;
            break;
            }

            if( foundnode && _node.NodeType == XmlNodeType.Whitespace && _whitespaceHandling == WhitespaceHandling.None ) {
              // strip out whitespace (caller is probably pretty printing the XML).
              foundnode = false;
            }

            if( foundnode || _state != State.Eof || _stack.Count <= 1 ) continue;

            _popToDepth = 1;
            _state = State.AutoClose;
            _node = Top();
            return true;
              }

              if( !_foundRoot && ( NodeType == XmlNodeType.Element || NodeType == XmlNodeType.Text || NodeType == XmlNodeType.CDATA ) ) {
            _foundRoot = true;
            if( IsHtml && ( NodeType != XmlNodeType.Element || !LocalName.EqualsIgnoreCase( "html" ) ) ) {
              // Simulate an HTML root element!
              _node.CurrentState = _state;
              var root = Push( "html", XmlNodeType.Element, null );
              SwapTopNodes(); // make html the outer element.
              _node = root;
              root.Simulated = true;
              root.IsEmpty = false;
              _state = State.Markup;
            }

            return true;
              }

              return true;
        }
Ejemplo n.º 4
0
 private void Push( Node n )
 {
     // we have to do a deep clone of the Node object because
       // it is reused in the stack.
       var n2 = Push( n.Name, n.NodeType, n.Value );
       n2.DtdType = n.DtdType;
       n2.IsEmpty = n.IsEmpty;
       n2.Space = n.Space;
       n2.XmlLang = n.XmlLang;
       n2.CurrentState = n.CurrentState;
       n2.CopyAttributes( n );
       _node = n2;
       return;
 }
Ejemplo n.º 5
0
        private void Validate( Node node )
        {
            if( _dtd == null ) return;

              var e = _dtd.FindElement( node.Name );
              if( e == null ) return;

              node.DtdType = e;
              if( e.ContentModel.DeclaredContent == DeclaredContent.EMPTY )
            node.IsEmpty = true;
        }
Ejemplo n.º 6
0
        private Node Push( string name, XmlNodeType nt, string value )
        {
            var result = (Node) _stack.Push();
              if( result == null ) {
            result = new Node();
            _stack[ _stack.Count - 1 ] = result;
              }

              result.Reset( name, nt, value );
              _node = result;
              return result;
        }
Ejemplo n.º 7
0
 private void Pop()
 {
     if( _stack.Count > 1 ) {
     _node = (Node) _stack.Pop();
       }
 }
Ejemplo n.º 8
0
        private bool ParseEndTag()
        {
            _state = State.EndTag;
              _current.ReadChar(); // consume '/' char.
              var name = ScanName( Tagterm );
              var ch = _current.SkipWhitespace();
              if( ch != '>' ) {
            Log( "Expected empty start tag '/>' sequence instead of '{0}'", ch );
            _current.ScanToEnd( null, "Recovering", ">" );
              }

              _current.ReadChar(); // consume '>'

              _endTag = name;

              // Make sure there's a matching start tag for it.
              var caseInsensitive = ( _folding == CaseFolding.None );
              _node = (Node) _stack[ _stack.Count - 1 ];
              for( var i = _stack.Count - 1; i > 0; i-- ) {
            var n = (Node) _stack[ i ];
            if( !n.Name.Equals( name, caseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal ) ) continue;

            _endTag = n.Name;
            return true;
              }

              Log( "No matching start tag for '</{0}>'", name );
              _state = State.Markup;
              return false;
        }
Ejemplo n.º 9
0
 private void Init()
 {
     _state = State.Initial;
       _stack = new HwStack( 10 );
       _node = Push( null, XmlNodeType.Document, null );
       _node.IsEmpty = false;
       _sb = new StringBuilder();
       _name = new StringBuilder();
       _popToDepth = 0;
       _current = null;
       _partial = '\0';
       _endTag = null;
       _attribute = null;
       _attributePos = 0;
       _newNode = null;
       _rootCount = 0;
       _foundRoot = false;
       _unknownNamespaces.Clear();
 }
Ejemplo n.º 10
0
        private static void ValidateAttribute( Node node, Attribute a )
        {
            var e = node.DtdType;
              if( e == null ) return;

              var ad = e.FindAttribute( a.Name );
              if( ad != null ) {
            a.DtdType = ad;
              }
        }