Пример #1
0
        /// <summary>
        /// 解析字符串
        /// </summary>
        /// <param name="ownerTemplate">宿主模板</param>
        /// <param name="container">标签的容器</param>
        /// <param name="text">模板文本数据</param>
        private void ParseString(Template ownerTemplate, Tag container, string text)
        {
            //设置根文档模板
            this.DocumentElement = ownerTemplate;
            //this.Text = text;

            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            int   charOffset = 0, offset = 0;
            bool  isClosedTag;
            Match match = null;

            //标签堆栈
            Stack <Tag> tagStack = new Stack <Tag>();

            tagStack.Push(container);

            try
            {
                while (offset < text.Length)
                {
                    if (ParserHelper.IsVariableTagStart(text, offset) && (match = ParserRegex.VarTagRegex.Match(text, offset)).Success)  //匹配到模板变量
                    {
                        //构建文本节点
                        ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, match.Index - charOffset);
                        //构建模板变量
                        ParserHelper.CreateVariableTag(ownerTemplate, container, match);
                    }
                    else if (ParserHelper.IsTagStart(text, offset) && (match = ParserRegex.TagRegex.Match(text, offset)).Success)  //匹配到某种类型的标签
                    {
                        //构建文本节点
                        ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, match.Index - charOffset);
                        //构建标签
                        Tag tag = ParserHelper.CreateTag(ownerTemplate, match, out isClosedTag);

                        //将标签加入堆栈
                        tagStack.Push(tag);
                        //将解析权交给标签
                        bool flag = tag.ProcessBeginTag(ownerTemplate, container, tagStack, text, ref match, isClosedTag);
                        //非已闭合标签或者是单标签则处理标签的结束标签
                        if (flag)
                        {
                            tag.ProcessEndTag(ownerTemplate, tag, tagStack, text, ref match);
                        }
                        if (tagStack.Count > 0 && tagStack.Peek() == tag && isClosedTag)
                        {
                            //闭合标签则回滚一级
                            tagStack.Pop();
                        }
                        //取得容器
                        if (tagStack.Count > 0)
                        {
                            container = tagStack.Peek();
                        }
                    }
                    else if (ParserHelper.IsCloseTagStart(text, offset) && (match = ParserRegex.EndTagRegex.Match(text, offset)).Success)            //匹配到某个结束标签
                    {
                        //取得标签名称
                        string name = match.Groups["tagname"].Value;
                        //非匹配的结束标签.则模板有错
                        throw new ParserException("无效的结束标签");
                    }
                    else if (ParserHelper.IsVTExpressionStart(text, offset))
                    {
                        char s           = ParserHelper.ReadChar(text, offset + ParserHelper.VTExpressionHead.Length);
                        int  startOffset = offset + ParserHelper.VTExpressionHead.Length + 1;
                        int  lastOffset  = text.IndexOf(s, offset + ParserHelper.VTExpressionHead.Length + 1);
                        if (lastOffset == -1)
                        {
                            throw new ParserException(string.Format("无法找到VT表达式\"{0}\"的结束标记", ParserHelper.VTExpressionHead));
                        }
                        string code = text.Substring(startOffset, lastOffset - startOffset);
                        if (code.Length > 0)
                        {
                            //构建文本节点
                            ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, offset - charOffset);
                            //解析表达式里的代码
                            new TemplateDocument(ownerTemplate, container, code, ownerTemplate.OwnerDocument.DocumentConfig);
                        }
                        offset     = lastOffset + 1;
                        charOffset = offset;
                        continue;
                    }
                    else if (ParserHelper.IsCommentTagStart(text, offset))
                    {
                        //构建文本节点
                        ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, offset - charOffset);

                        //找到注释的起始标记"<!--vt[",则直接查找结束标记"]-->"
                        offset = text.IndexOf(ParserHelper.CommentTagEnd, offset + ParserHelper.CommentTagStart.Length);
                        if (offset == -1)
                        {
                            throw new ParserException("无法找到注释的结束标记");
                        }
                        offset    += ParserHelper.CommentTagEnd.Length;
                        charOffset = offset;
                        continue;
                    }
                    //处理偏移位置
                    if (match != null && match.Success)
                    {
                        charOffset = offset = match.Index + match.Length;
                        match      = null;
                    }
                    else
                    {
                        offset++;
                    }
                }
                //处理文本字符
                ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, text.Length - charOffset);
                if (tagStack.Count > 1)
                {
                    //堆栈里还有其它元素.则有错误
                    throw new ParserException(string.Format("{0}标签未闭合", tagStack.Pop()));
                }
            }
            catch (ParserException ex)
            {
                //如果错误中不包含行号与列号.则计算行号与列号
                if (!ex.HaveLineAndColumnNumber && match != null && match.Success)
                {
                    //获取当前出错时正在解析的模板文件
                    string file = string.Empty;
                    Tag    tag  = container;
                    while (string.IsNullOrEmpty(file) && tag != null)
                    {
                        if (tag is Template)
                        {
                            file = ((Template)tag).File;
                        }
                        else if (tag is IncludeTag)
                        {
                            file = ((IncludeTag)tag).File;
                        }
                        tag = tag.Parent;
                    }
                    if (string.IsNullOrEmpty(file))
                    {
                        throw new ParserException(Utility.GetLineAndColumnNumber(text, match.Index), match.ToString(), ex.Message);
                    }
                    else
                    {
                        throw new ParserException(file, Utility.GetLineAndColumnNumber(text, match.Index), match.ToString(), ex.Message);
                    }
                }
                else
                {
                    //继续抛出错误
                    throw;
                }
            }
            finally
            {
                //清空堆栈
                tagStack.Clear();
                tagStack = null;
            }
        }