예제 #1
0
 public void CopyAttributes(Node n)
 {
     for (int i = 0, len = n.attributes.Count; i < len; i++)
     {
         Attribute a = (Attribute)n.attributes[i];
         Attribute na = this.AddAttribute(a.Name, a.Value, a.QuoteChar, false);
         na.DtdType = a.DtdType;
     }
 }
예제 #2
0
 void Init()
 {
     this.state = State.Initial;
     this.stack = new HWStack(10);
     this.node = Push(null, XmlNodeType.Document, null);
     this.node.IsEmpty = false;
     this.sb = new StringBuilder();
     this.name = new StringBuilder();
     this.poptodepth = 0;
     this.current = null;
     this.partial = '\0';
     this.endTag = null;
     this.a = null;
     this.apos = 0;
     this.newnode = null;
     this.rootCount = 0;
     this.foundRoot = false;
 }
예제 #3
0
        public override bool Read()
        {
            if (current == null)
            {
                OpenInput();
            }
            State start = this.state;
            if (node.Simulated)
            {
                node.Simulated = false;
                this.node = Top();
                this.state = this.node.CurrentState;
                return true;
            }

            bool foundnode = false;
            while (!foundnode)
            {
                switch (this.state)
                {
                    case State.Initial:
                        this.state = State.Markup;
                        this.current.ReadChar();
                        goto case State.Markup;
                    case State.Eof:
                        if (this.current.Parent != null)
                        {
                            this.current.Close();
                            this.current = this.current.Parent;
                        }
                        else
                        {
                            return false;
                        }
                        break;
                    case State.EndTag:
                        if (this.endTag == (object)this.node.Name)
                        {
                            Pop(); // we're done!
                            this.state = State.Markup;
                            goto case State.Markup;
                        }
                        Pop();
                        foundnode = true;
                        break;
                    case State.Markup:
                        if (this.node.IsEmpty)
                        {
                            Pop();
                        }
                        Node n = this.node;
                        foundnode = ParseMarkup();
                        break;
                    case State.PartialTag:
                        Pop();
                        this.state = State.Markup;
                        foundnode = ParseTag(this.partial);
                        break;
                    case State.PseudoStartTag:
                        foundnode = ParseStartTag('<');
                        break;
                    case State.AutoClose:
                        Pop();
                        if (this.stack.Count <= this.poptodepth)
                        {
                            this.state = State.Markup;
                            if (this.newnode != null)
                            {
                                Push(this.newnode);
                                this.newnode = null;
                                this.state = State.Markup;
                            }
                            else if (this.node.NodeType == XmlNodeType.Document)
                            {
                                this.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:
                        this.state = State.Markup;
                        goto case State.Markup;
                    case State.Text:
                        Pop();
                        goto case State.Markup;
                    case State.PartialText:
                        if (ParseText(this.current.Lastchar, false))
                        {
                            this.node.NodeType = XmlNodeType.Whitespace;
                        }
                        foundnode = true;
                        break;
                }
                if (foundnode && this.node.NodeType == XmlNodeType.Whitespace && this.whitespaceHandling == WhitespaceHandling.None)
                {

                    foundnode = false;
                }
                if (!foundnode && this.state == State.Eof && this.stack.Count > 1)
                {
                    this.poptodepth = 1;
                    state = State.AutoClose;
                    this.node = Top();
                    return true;
                }
            }
            if (!foundRoot && (this.NodeType == XmlNodeType.Element ||
                    this.NodeType == XmlNodeType.Text ||
                    this.NodeType == XmlNodeType.CDATA))
            {
                foundRoot = true;
                if (this.IsHtml && (this.NodeType != XmlNodeType.Element ||
                    string.Compare(this.LocalName, "html", true, System.Globalization.CultureInfo.InvariantCulture) != 0))
                {

                    this.node.CurrentState = this.state;
                    Node root = Push("html", XmlNodeType.Element, null);
                    SwapTopNodes();
                    this.node = root;
                    root.Simulated = true;
                    root.IsEmpty = false;
                    this.state = State.Markup;
                }
                return true;
            }
            return true;
        }
예제 #4
0
        void ValidateContent(Node node)
        {
            if (this.dtd != null)
            {
                string name = this.nametable.Add(node.Name.ToUpper());
                int i = 0;
                int top = this.stack.Count - 2;
                if (node.DtdType != null)
                {
                    for (i = top; i > 0; i--)
                    {
                        Node n = (Node)this.stack[i];
                        if (n.IsEmpty)
                            continue;
                        ElementDecl f = n.DtdType;
                        if (f != null)
                        {
                            if (f.Name == this.dtd.Name)
                                break;
                            if (f.CanContain(name, this.dtd))
                            {
                                break;
                            }
                            else if (!f.EndTagOptional)
                            {

                                break;
                            }
                        }
                        else
                        {

                            break;
                        }
                    }
                }
                if (i == 0)
                {

                }
                else if (i < top)
                {
                    Node n = (Node)this.stack[top];
                    if (i == top - 1 && name == n.Name)
                    {

                    }
                    else
                    {
                        string closing = "";
                        for (int k = top; k >= i + 1; k--)
                        {
                            if (closing != "") closing += ",";
                            Node n2 = (Node)this.stack[k];
                            closing += "<" + n2.Name + ">";
                        }
                        Log("Element '{0}' not allowed inside '{1}', closing {2}.",
                            name, n.Name, closing);
                    }
                    this.state = State.AutoClose;
                    this.newnode = node;
                    Pop();
                    this.poptodepth = i + 1;
                }
            }
        }
예제 #5
0
 void ValidateAttribute(Node node, Attribute a)
 {
     ElementDecl e = node.DtdType;
     if (e != null)
     {
         AttDef ad = e.FindAttribute(a.Name);
         if (ad != null)
         {
             a.DtdType = ad;
         }
     }
 }
예제 #6
0
 void Validate(Node node)
 {
     if (this.dtd != null)
     {
         ElementDecl e = this.dtd.FindElement(node.Name);
         if (e != null)
         {
             node.DtdType = e;
             if (e.ContentModel.DeclaredContent == DeclaredContent.EMPTY)
                 node.IsEmpty = true;
         }
     }
 }
예제 #7
0
 Node Push(Node n)
 {
     Node 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);
     this.node = n2;
     return n2;
 }
예제 #8
0
 Node Push(string name, XmlNodeType nt, string value)
 {
     Node result = (Node)this.stack.Push();
     if (result == null)
     {
         result = new Node();
         this.stack[this.stack.Count - 1] = result;
     }
     result.Reset(name, nt, value);
     this.node = result;
     return result;
 }
예제 #9
0
 void Pop()
 {
     if (this.stack.Count > 1)
     {
         this.node = (Node)this.stack.Pop();
     }
 }
예제 #10
0
        bool ParseEndTag()
        {
            this.state = State.EndTag;
            this.current.ReadChar();
            string name = this.ScanName(SgmlReader.tagterm);
            char ch = this.current.SkipWhitespace();
            if (ch != '>')
            {
                Log("Expected empty start tag '/>' sequence instead of '{0}'", ch);
                this.current.ScanToEnd(null, "Recovering", ">");
            }
            this.current.ReadChar();

            this.endTag = name;

            bool caseInsensitive = (this.folding == CaseFolding.None);
            this.node = (Node)this.stack[this.stack.Count - 1];
            for (int i = this.stack.Count - 1; i > 0; i--)
            {
                Node n = (Node)this.stack[i];
                if (caseInsensitive && string.Compare(n.Name, name, true) == 0)
                {
                    this.endTag = n.Name;
                    return true;
                }
                else if ((object)n.Name == (object)name)
                {
                    return true;
                }
            }
            Log("No matching start tag for '</{0}>'", name);
            this.state = State.Markup;
            return false;
        }