예제 #1
0
파일: XmlParser.cs 프로젝트: wnf0000/Eto
        public static XmlParseInfo Read(string text)
        {
            var nodes = new List <CompletionPathNode>();
            var info  = new XmlParseInfo {
                Nodes = nodes, Mode = CompletionMode.Class
            };

            // complete the last node and/or attribute so the reader can find it.
            string supplement = null;
            bool   hadLetter  = false;
            char   last       = char.MinValue;

            for (int i = text.Length - 1; i >= 0; i--)
            {
                var ch = text[i];
                if (ch == '<')
                {
                    if (i == text.Length - 1)
                    {
                        break;
                    }
                    if (last == '/')                     // we're in an ending tag
                    {
                        info.Mode = CompletionMode.None;
                    }
                    if (supplement != null)
                    {
                        text += supplement;
                    }
                    text += ">";
                    break;
                }
                if (ch == '>')
                {
                    info.Mode = CompletionMode.Class;
                    break;
                }
                if (info.Mode == CompletionMode.Class)
                {
                    if (ch == '=')
                    {
                        info.Mode  = CompletionMode.Value;
                        text       = text.Substring(0, i + 1);
                        supplement = "''";
                    }
                    if (ch == '.')
                    {
                        info.Mode = CompletionMode.Property;
                    }
                    if (ch == ' ')
                    {
                        info.Mode = CompletionMode.Property;
                        if (hadLetter)
                        {
                            supplement = "=''";
                        }
                    }
                    if (char.IsLetterOrDigit(ch))
                    {
                        hadLetter = true;
                    }
                }
                last = ch;
            }

            CompletionPathNode current   = null;
            CompletionPathNode attribute = null;

            try
            {
                using (var stream = GetStream(text))
                    using (var reader = XmlReader.Create(stream))
                    {
                        while (reader.Read())
                        {
                            attribute = null;
                            switch (reader.NodeType)
                            {
                            case XmlNodeType.Element:
                                if (reader.IsEmptyElement)
                                {
                                    continue;
                                }
                                nodes.Add(current = new CompletionPathNode(reader.Prefix, reader.LocalName, CompletionMode.Class));
                                if (reader.HasAttributes && reader.MoveToFirstAttribute())
                                {
                                    do
                                    {
                                        if (reader.Name == "xmlns" || reader.Prefix == "xmlns")
                                        {
                                            // record namespaces
                                            if (current.Namespaces == null)
                                            {
                                                current.Namespaces = new List <CompletionNamespace>();
                                            }
                                            var prefix = reader.Prefix == "xmlns" ? reader.LocalName : string.Empty;
                                            current.Namespaces.Add(new CompletionNamespace {
                                                Prefix = prefix, Namespace = reader.Value
                                            });
                                        }
                                        else
                                        {
                                            current.Attributes.Add(reader.Name);
                                            attribute = new CompletionPathNode(reader.Prefix, reader.LocalName, CompletionMode.Property);
                                        }
                                    } while (reader.MoveToNextAttribute());
                                }
                                break;

                            case XmlNodeType.EndElement:
                                if (nodes.Count > 0)
                                {
                                    nodes.RemoveAt(nodes.Count - 1);
                                }
                                current = nodes.Count > 0 ? nodes[nodes.Count - 1] : null;
                                break;

                            default:
                                break;
                            }
                        }
                    }
            }
            catch (XmlException)
            {
                // ignore errors, since xml will usually be incomplete
            }

            if (info.Mode == CompletionMode.Value && attribute != null)
            {
                nodes.Add(attribute);
            }

            return(info);
        }
예제 #2
0
        public static XmlParseInfo Read(string text)
        {
            var nodes = new List <CompletionPathNode>();
            var info  = new XmlParseInfo {
                Nodes = nodes, Mode = CompletionMode.None
            };

            // check the last part of the xml to see what type of completion we are in
            // and complete it so we can parse the property or class name.
            Match m;

            if ((m = valueReg.Match(text)).Success)
            {
                info.Mode = CompletionMode.Value;
                // without an actual value, xmlns doesn't parse, so put a dummy value here
                text = text.Substring(0, m.Index) + "'value'>";
            }
            else if (classReg.Match(text).Success)
            {
                info.Mode = CompletionMode.Class;
                text     += ">";
            }
            else if (propertyReg.Match(text).Success)
            {
                int i = text.Length - 1;
                while (i > 0 && !char.IsWhiteSpace(text[i]) && text[i] != '<')
                {
                    i--;
                }
                if (i < text.Length - 1)
                {
                    text = text.Substring(0, i + 1);
                }

                info.Mode = CompletionMode.Property;
                text     += ">";
            }
            else if (classPropertyReg.Match(text).Success)
            {
                info.Mode            = CompletionMode.Property;
                info.IsChildProperty = true;
                text += ">";
            }


            CompletionPathNode current   = null;
            CompletionPathNode attribute = null;

            try
            {
                using (var reader = XmlReader.Create(new StringReader(text)))
                {
                    while (reader.Read())
                    {
                        attribute = null;
                        switch (reader.NodeType)
                        {
                        case XmlNodeType.Element:
                            if (reader.IsEmptyElement)
                            {
                                continue;
                            }
                            nodes.Add(current = new CompletionPathNode(reader.Prefix, reader.LocalName, CompletionMode.Class));
                            if (reader.HasAttributes && reader.MoveToFirstAttribute())
                            {
                                do
                                {
                                    if (reader.Name == "xmlns" || reader.Prefix == "xmlns")
                                    {
                                        // record namespaces
                                        if (current.Namespaces == null)
                                        {
                                            current.Namespaces = new List <CompletionNamespace>();
                                        }
                                        var prefix = reader.Prefix == "xmlns" ? reader.LocalName : string.Empty;
                                        current.Namespaces.Add(new CompletionNamespace {
                                            Prefix = prefix, Namespace = reader.Value
                                        });
                                        var name = reader.LocalName;
                                        if (!string.IsNullOrEmpty(reader.Prefix))
                                        {
                                            name = reader.Prefix + ":" + name;
                                        }
                                        attribute = new CompletionPathNode(string.Empty, name, CompletionMode.Property);
                                    }
                                    else
                                    {
                                        current.Attributes.Add(reader.Name);
                                        attribute = new CompletionPathNode(reader.Prefix, reader.LocalName, CompletionMode.Property);
                                    }
                                } while (reader.MoveToNextAttribute());
                            }
                            break;

                        case XmlNodeType.EndElement:
                            if (nodes.Count > 0)
                            {
                                nodes.RemoveAt(nodes.Count - 1);
                            }
                            current = nodes.Count > 0 ? nodes[nodes.Count - 1] : null;
                            break;

                        default:
                            break;
                        }
                    }
                }
            }
            catch (XmlException)
            {
                // ignore errors, since xml will usually be incomplete
            }

            if (current?.LocalName.Contains(".") == true && info.Mode == CompletionMode.None && current.Mode == CompletionMode.Class)
            {
                current.LocalName = current.LocalName.Substring(current.LocalName.IndexOf('.') + 1);
                current.Mode      = CompletionMode.Property;
                info.Mode         = CompletionMode.Value;
            }

            if (info.Mode == CompletionMode.Value && attribute != null)
            {
                nodes.Add(attribute);
            }

            return(info);
        }
예제 #3
0
파일: XmlParser.cs 프로젝트: yaram/Eto
        public static XmlParseInfo Read(string text)
        {
            var nodes = new List <CompletionPathNode>();
            var info  = new XmlParseInfo {
                Nodes = nodes, Mode = CompletionMode.None
            };

            // check the last part of the xml to see what type of completion we are in
            // and complete it so we can parse the property or class name.
            var m = valueReg.Match(text);

            if (m.Success)
            {
                info.Mode = CompletionMode.Value;
                text      = text.Substring(0, m.Index) + "''>";
            }
            else
            {
                m = classReg.Match(text);
                if (m.Success)
                {
                    info.Mode = CompletionMode.Class;
                }
                else
                {
                    m = propertyReg.Match(text);
                    if (m.Success)
                    {
                        info.Mode = CompletionMode.Property;
                    }
                }
                text += ">";
            }


            CompletionPathNode current   = null;
            CompletionPathNode attribute = null;

            try
            {
                using (var stream = GetStream(text))
                    using (var reader = XmlReader.Create(stream))
                    {
                        while (reader.Read())
                        {
                            attribute = null;
                            switch (reader.NodeType)
                            {
                            case XmlNodeType.Element:
                                if (reader.IsEmptyElement)
                                {
                                    continue;
                                }
                                nodes.Add(current = new CompletionPathNode(reader.Prefix, reader.LocalName, CompletionMode.Class));
                                if (reader.HasAttributes && reader.MoveToFirstAttribute())
                                {
                                    do
                                    {
                                        if (reader.Name == "xmlns" || reader.Prefix == "xmlns")
                                        {
                                            // record namespaces
                                            if (current.Namespaces == null)
                                            {
                                                current.Namespaces = new List <CompletionNamespace>();
                                            }
                                            var prefix = reader.Prefix == "xmlns" ? reader.LocalName : string.Empty;
                                            current.Namespaces.Add(new CompletionNamespace {
                                                Prefix = prefix, Namespace = reader.Value
                                            });
                                        }
                                        else
                                        {
                                            current.Attributes.Add(reader.Name);
                                            attribute = new CompletionPathNode(reader.Prefix, reader.LocalName, CompletionMode.Property);
                                        }
                                    } while (reader.MoveToNextAttribute());
                                }
                                break;

                            case XmlNodeType.EndElement:
                                if (nodes.Count > 0)
                                {
                                    nodes.RemoveAt(nodes.Count - 1);
                                }
                                current = nodes.Count > 0 ? nodes[nodes.Count - 1] : null;
                                break;

                            default:
                                break;
                            }
                        }
                    }
            }
            catch (XmlException)
            {
                // ignore errors, since xml will usually be incomplete
            }

            if (info.Mode == CompletionMode.Value && attribute != null)
            {
                nodes.Add(attribute);
            }

            return(info);
        }