예제 #1
0
        public void CopyAttributes(SgmlNode node)
        {
            Precondition.Require(node, () => Error.ArgumentNull("node"));

            int index = 0;
            int count = node._attributes.Count;

            while (index < count)
            {
                Attribute attribute = node._attributes[index];
                AddAttribute(attribute.Name, attribute.Value,
                             attribute.QuoteChar, false).DtdType = attribute.DtdType;

                index++;
            }
        }
예제 #2
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)
            {
                _node.Simulated = false;
                _node = Top();
                _state = _node.State;

                return true;
            }

            bool 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 (String.Equals(_endTag, _node.Name,
                            StringComparison.InvariantCultureIgnoreCase))
                        {
                            Pop();
                            _state = State.Markup;
                            goto case State.Markup;
                        }
                        Pop();
                        foundNode = true;

                        break;
                    case State.Markup:
                        if (_node.IsEmpty)
                            Pop();

                        foundNode = ParseMarkup();
                        break;
                    case State.PartialTag:
                        Pop();
                        _state = State.Markup;
                        foundNode = ParseTag(_partial);
                        break;
                    case State.PseudoStartTag:
                        foundNode = ParseStartTag('<');
                        break;
                    case State.AutoClose:
                        Pop();
                        if (_stack.Count <= _popToDepth)
                        {
                            _state = State.Markup;
                            if (_newNode != null)
                            {
                                Push(_newNode);

                                _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)
                    foundNode = false;

                if (!foundNode && _state == State.Eof && _stack.Count > 1)
                {
                    _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 ||
                    !String.Equals(LocalName, "html",
                    StringComparison.InvariantCultureIgnoreCase)))
                {
                    _node.State = _state;
                    SgmlNode root = Push("html", XmlNodeType.Element, null);

                    SwapTopNodes();
                    _node = root;
                    root.Simulated = true;
                    root.IsEmpty = false;

                    _state = State.Markup;
                }
                return true;
            }
            return true;
        }
예제 #3
0
 private static void ValidateAttribute(SgmlNode node, Attribute a)
 {
     ElementDeclaration e = node.DtdType;
     if (e != null)
     {
         AttributeDefinition ad = e.FindAttribute(a.Name);
         if (ad != null)
             a.DtdType = ad;
     }
 }
예제 #4
0
        private void ValidateContent(SgmlNode node)
        {
            if (node.NodeType == XmlNodeType.Element)
            {
                if (!VerifyName(node.Name))
                {
                    Pop();
                    Push(null, XmlNodeType.Text, "<" + node.Name + ">");

                    return;
                }
            }

            if (_dtd != null)
            {
                string name = node.Name.ToUpper(CultureInfo.InvariantCulture);
                int i = 0;
                int top = _stack.Count - 2;

                if (node.DtdType != null)
                {
                    for (i = top; i > 0; i--)
                    {
                        SgmlNode n = _stack[i];
                        if (n.IsEmpty)
                            continue;

                        ElementDeclaration f = n.DtdType;
                        if (f != null)
                        {
                            if (i == 2 && String.Equals(f.Name, "BODY",
                                StringComparison.InvariantCultureIgnoreCase))
                                break;

                            else if (String.Equals(f.Name, _dtd.Name,
                                StringComparison.InvariantCultureIgnoreCase))
                                break;

                            else if (f.CanContain(name, _dtd))
                                break;

                            else if (!f.EndTagOptional)
                                break;
                        }
                        else
                            break;
                    }
                }

                if (i == 0)
                {
                    return;
                }
                else if (i < top)
                {
                    SgmlNode n = _stack[top];
                    if (i == top - 1 && String.Equals(name, n.Name, 
                        StringComparison.InvariantCultureIgnoreCase))
                    {
                        // e.g. p not allowed inside p, not an interesting error.
                    }
                    else
                    {
#if DEBUG
                        string closing = "";
                        for (int k = top; k >= i+1; k--) 
                        {
                            
                            if (closing != "") 
                                closing += ",";

                            SgmlNode n2 = _stack[k];
                            closing += "<" + n2.Name + ">";
                        }
                        Log("Element '{0}' not allowed inside '{1}', closing {2}.", name, n.Name, closing);
#endif
                    }

                    _state = State.AutoClose;
                    _newNode = node;
                    Pop(); 

                    _popToDepth = i + 1;
                }
            }
        }
예제 #5
0
 private void Validate(SgmlNode node)
 {
     if (_dtd != null)
     {
         ElementDeclaration e = _dtd.FindElement(node.Name);
         if (e != null)
         {
             node.DtdType = e;
             if (e.ContentModel.DeclaredContent == DeclaredContent.Empty)
                 node.IsEmpty = true;
         }
     }
 }
예제 #6
0
        private bool ParseEndTag()
        {
            _state = State.EndTag;
            _current.ReadChar();
            string name = ScanName(_tagTerm);
            char ch = _current.SkipWhitespace();

            if (ch != '>')
            {
                Log("Expected empty start tag '/>' sequence instead of '{0}'", ch);
                _current.ScanToEnd(_builder, "Recovering", ">");
            }

            _current.ReadChar();
            _endTag = name;

            bool caseInsensitive = (_folding == CaseFolding.None);
            _node = _stack[_stack.Count - 1];

            for (int i = _stack.Count - 1; i > 0; i--)
            {
                SgmlNode n = _stack[i];
                if (String.Compare(n.Name, name, caseInsensitive, 
                    CultureInfo.InvariantCulture) == 0)
                {
                    _endTag = n.Name;
                    return true;
                }
            }

            Log("No matching start tag for '</{0}>'", name);
            _state = State.Markup;

            return false;
        }
예제 #7
0
 private void Pop()
 {
     if (_stack.Count > 1)
         _node = _stack.Pop();
 }
예제 #8
0
        private SgmlNode Push(SgmlNode n)
        {
            SgmlNode 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.State = n.State;
            n2.CopyAttributes(n);
            _node = n2;

            return n2;
        }
예제 #9
0
        private SgmlNode Push(string name, XmlNodeType nodeType, string value)
        {
            SgmlNode result = _stack.Push();
            if (result == null)
            {
                result = new SgmlNode();
                _stack[_stack.Count - 1] = result;
            }

            result.Reset(name, nodeType, value);
            _node = result;

            return result;
        }
예제 #10
0
 protected virtual void Init()
 {
     _state = State.Initial;
     _stack = new HWStack<SgmlNode>(10);
     _node = Push(null, XmlNodeType.Document, null);
     _node.IsEmpty = false;
     _builder = new StringBuilder();
     _nameBuilder = new StringBuilder();
     _popToDepth = 0;
     _current = null;
     _partial = '\0';
     _endTag = null;
     _attr = null;
     _attrPosition = 0;
     _newNode = null;
     _rootCount = 0;
     _foundRoot = false;
     _unknownNamespaces.Clear();
 }
예제 #11
0
        public void CopyAttributes(SgmlNode node)
        {
            Precondition.Require(node, () => Error.ArgumentNull("node"));

            int index = 0;
            int count = node._attributes.Count;

            while (index < count)
            {
                Attribute attribute = node._attributes[index];
                AddAttribute(attribute.Name, attribute.Value, 
                    attribute.QuoteChar, false).DtdType = attribute.DtdType;

                index++;
            }
        }