Ejemplo n.º 1
0
        /// <summary>
        /// 结束标签的解析
        /// </summary>
        /// <param name="ownerTemplate">模板宿主</param>
        /// <param name="container">元素容器</param>
        /// <param name="tagStack">标签堆栈</param>
        /// <param name="text"></param>
        /// <param name="match"></param>
        internal virtual void ProcessEndTag(Template ownerTemplate, Tag container, Stack <Tag> tagStack, string text, ref Match match)
        {
            int  charOffset = 0, offset = 0;
            bool isClosedTag;

            charOffset = offset = match.Index + match.Length;
            match      = null;
            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);

                    if (container.IsSingleTag && tag.IsSingleTag)
                    {
                        //如果前容器是单一标签并且当前标签也是单一标签.则回退到上一级非单元素标签
                        while (tagStack.Count > 0)
                        {
                            container = tagStack.Peek();
                            if (container.IsSingleTag)
                            {
                                tagStack.Pop();
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    //将当前标签加入堆栈
                    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 (tag.IsSingleTag)
                    {
                        //如果标签是单标签则退出寻找
                        break;
                    }
                    else
                    {
                        //取得容器
                        if (tagStack.Count > 0)
                        {
                            container = tagStack.Peek();
                        }
                    }
                }
                else if (ParserHelper.IsCloseTagStart(text, offset) && (match = ParserRegex.EndTagRegex.Match(text, offset)).Success)            //匹配到某个结束标签
                {
                    //构建文本节点
                    ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, match.Index - charOffset);
                    //取得标签名称
                    string name = match.Groups["tagname"].Value;

                    //回滚标签堆栈.直到回滚到同名称元素的上级为此
                    while (tagStack.Count > 0)
                    {
                        Tag popTag = tagStack.Pop();
                        if (name.Equals(popTag.TagName, StringComparison.InvariantCultureIgnoreCase))
                        {
                            break;
                        }
                        if (!name.Equals(popTag.EndTagName, StringComparison.InvariantCultureIgnoreCase))
                        {
                            //非匹配的结束标签.则模板有错
                            throw new ParserException(string.Format("无效的结束标签,原期望的是{0}结束标签", popTag.EndTagName));
                        }
                    }
                    break;
                }
                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}{1}]的结束标记[{1}]", ParserHelper.VTExpressionHead, s));
                    }
                    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++;
                }
            }

            if (match == null)
            {
                throw new ParserException(string.Format("{0}标签未闭合", container.TagName));
            }
        }
Ejemplo n.º 2
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;
            }
        }