Exemple #1
0
 /// <summary>
 /// 标签元素
 /// </summary>
 /// <param name="ownerTemplate">宿主模板</param>
 protected Tag(Template ownerTemplate) : base(ownerTemplate)
 {            
     this.InnerElements = new ElementCollection<Element>();
     this.Attributes = new AttributeCollection(this);
     //注册添加属性时触发事件.用于设置自身的某些属性值
     this.Attributes.Adding += OnAddingAttribute;
 }
Exemple #2
0
        /// <summary>
        /// 从表达式文本中构造表达式.如果表达式是以$字符开头.并且不是以$$字符开头.则认为是变量表达式.否则则认为是常量表达式
        /// </summary>
        /// <param name="ownerTemplate"></param>
        /// <param name="expressionText"></param>
        /// <returns></returns>
        internal static IExpression CreateExpression(Template ownerTemplate, string expressionText)
        {
            if (string.IsNullOrEmpty(expressionText)) return new ConstantExpression(expressionText);

            if (expressionText.StartsWith("$") && !"$=".Equals(expressionText)) //"$="认为是字符串常量
            {
                expressionText = expressionText.Remove(0, 1);
                if (expressionText.StartsWith("$"))
                {
                    //$$字符开头.则认为是常量表达式
                    return new ConstantExpression(expressionText);
                }
                else
                {
                    //变量表达式
                    return CreateVariableExpression(ownerTemplate, expressionText, false);
                }
            }
            else
            {
                //常量表达式
                return Utility.IsInteger(expressionText) ?
                      new ConstantExpression(Utility.ConverToInt32(expressionText))
                    : new ConstantExpression(expressionText);
            }
        }
        /// <summary>
        /// 解析某个模板块的数据
        /// </summary>
        /// <param name="template"></param>
        public void PreRender(Template template)
        {
            //根据模板块里定义的type属性条件取得新闻数据
            List<News> newsData = NewsDbProvider.GetNewsData(template.Attributes.GetValue("type"));
            //设置变量newsdata的值
            template.Variables.SetValue("newsdata", newsData);

            //取得模板块下Id为newslist的标签(也即是在cnblogs_newsdata.html文件中定义的foreach标签)
            Tag tag = template.GetChildTagById("newslist");
            if (tag is ForEachTag)
            {
                //如果标签为foreach标签则设置其BeforeRender事件用于设置变量表达式{$:#.news.url}的值
                tag.BeforeRender += (sender, e) =>
                {
                    ForEachTag t = (ForEachTag)sender;

                    //取得当前项的值(因为foreach标签的数据源是List<News>集合,所以当前项的值类型为News实体)
                    News news = (News)t.Item.Value;
                    //设置当前项的变量表达式的值.也即是"{$:#.news.url}"变量表达式
                    t.Item.SetExpValue("url", NewsDbProvider.GetNewsUrl(news));

                    //当新闻不可见时.你可以取消本次输出
                    if (!news.Visible) e.Cancel = true;
                };
            }
        }
Exemple #4
0
 /// <summary>
 /// 克隆当前元素到新的宿主模板
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <returns></returns>
 internal override Element Clone(Template ownerTemplate)
 {
     IncludeTag tag = new IncludeTag(ownerTemplate);
     this.CopyTo(tag);
     tag.File = this.File;
     tag.Charset = this.Charset;
     return tag;
 }
 /// <summary>
 /// 带变量字段的初始化
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <param name="varExp"></param>
 internal VariableTag(Template ownerTemplate, VariableExpression varExp)
     : base(ownerTemplate)
 {
     //注册添加属性时触发事件.用于设置自身的某些属性值
     this.Attributes = new AttributeCollection(this);
     this.Attributes.Adding += OnAddingAttribute;
     this.VarExpression = varExp;
     this.CallFunctions = new List<IExpression>();
 }
Exemple #6
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ownerTemplate"></param>
 internal Template(Template ownerTemplate)
     : base(ownerTemplate)
 {
     this.Visible = true;
     this.Charset = (ownerTemplate == null ? Encoding.Default : ownerTemplate.Charset);
     this.Variables = new VariableCollection();
     this.ChildTemplates = new ElementCollection<Template>();
     this.fileDependencies = new List<string>();
     this.UserDefinedFunctions = new UserDefinedFunctionCollection();
     this.TagContainer = this;
 }
Exemple #7
0
        /// <summary>
        /// 构建标签元素
        /// </summary>
        /// <param name="ownerTemplate">宿主模板</param>
        /// <param name="match"></param>
        /// <param name="isClosedTag">是否是自闭合标签</param>
        /// <returns></returns>
        internal static Tag CreateTag(Template ownerTemplate, Match match,out bool isClosedTag)
        {
            string tagName = match.Groups["tagname"].Value;
            isClosedTag = match.Groups["closed"].Success;

            Tag tag = TagFactory.FromTagName(ownerTemplate, tagName);
            if (tag == null) throw new ParserException(string.Format("不能识别的元素标签\"{0}\"", tagName));

            ParseElementAttributes(tag, match);

            return tag;
        }
        /// <summary>
        /// 开始解析标签数据
        /// </summary>
        /// <param name="ownerTemplate">宿主模板</param>
        /// <param name="container">标签的容器</param>
        /// <param name="tagStack">标签堆栈</param>
        /// <param name="text"></param>
        /// <param name="match"></param>
        /// <param name="isClosedTag">是否闭合标签</param>
        /// <returns>如果需要继续处理EndTag则返回true.否则请返回false</returns>
        internal override bool ProcessBeginTag(Template ownerTemplate, Tag container, Stack<Tag> tagStack, string text, ref Match match, bool isClosedTag)
        {
            //判断标签的容器是否为ForEach标签
            if (!(container is ForEachTag)) throw new ParserException(string.Format("未找到和{0}标签对应的{1}标签", this.TagName, this.EndTagName));

            ForEachTag foreachTag = (ForEachTag)container;
            if (foreachTag.Else != null) throw new ParserException(string.Format("{0}标签不能定义多个{1}标签", this.EndTagName, this.TagName));

            foreachTag.Else = this;

            return true;
        }
Exemple #9
0
 /// <summary>
 /// 根据标签名建立标签实例
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <param name="tagName"></param>
 /// <returns></returns>
 internal static Tag FromTagName(Template ownerTemplate, string tagName)
 {
     if (!string.IsNullOrEmpty(tagName))
     {
         switch (tagName.ToLower())
         {
             case "for":
                 return new ForTag(ownerTemplate);
             case "foreach":
                 return new ForEachTag(ownerTemplate);
             case "foreachelse":
                 return new ForEachElseTag(ownerTemplate);
             case "if":
                 return new IfTag(ownerTemplate);
             case "elseif":
                 return new IfConditionTag(ownerTemplate);
             case "else":
                 return new ElseTag(ownerTemplate);
             case "template":
                 return new Template(ownerTemplate);
             case "include":
                 return new IncludeTag(ownerTemplate);
             case "expression":
                 return new ExpressionTag(ownerTemplate);
             case "function":
                 return new FunctionTag(ownerTemplate);
             case "property":
                 return new PropertyTag(ownerTemplate);
             case "serverdata":
                 return new ServerDataTag(ownerTemplate);
             case "set":
                 return new SetTag(ownerTemplate);
             case "import":
                 return new ImportTag(ownerTemplate);
             case "output":
                 return new OutputTag(ownerTemplate);
             case "panel":
                 return new PanelTag(ownerTemplate);
             case "datareader":
                 if (ownerTemplate.OwnerDocument.DocumentConfig != null
                     && ownerTemplate.OwnerDocument.DocumentConfig.TagOpenMode == TagOpenMode.Full)
                 {
                     return new DataReaderTag(ownerTemplate);
                 }
                 else
                 {
                     return null;
                 }
         }
     }
     return null;
 }
        /// <summary>
        /// 开始解析标签数据
        /// </summary>
        /// <param name="ownerTemplate">宿主模板</param>
        /// <param name="container">标签的容器</param>
        /// <param name="tagStack">标签堆栈</param>
        /// <param name="text"></param>
        /// <param name="match"></param>
        /// <param name="isClosedTag">是否闭合标签</param>
        /// <returns>如果需要继续处理EndTag则返回true.否则请返回false</returns>
        internal override bool ProcessBeginTag(Template ownerTemplate, Tag container, Stack<Tag> tagStack, string text, ref Match match, bool isClosedTag)
        {
            container.AppendChild(this);

            if (!string.IsNullOrEmpty(this.File))
            {
                //修正文件地址
                this.File = Utility.ResolveFilePath(this.Parent, this.File);

                if (System.IO.File.Exists(this.File))
                {
                    //增加到依赖文件列表
                    this.OwnerTemplate.AddFileDependency(this.File);

                    //解析数据
                    new TemplateDocument(ownerTemplate, this, System.IO.File.ReadAllText(this.File, this.Charset), ownerTemplate.OwnerDocument.DocumentConfig);
                }
            }
            return !isClosedTag;
        }
Exemple #11
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ownerTemplate"></param>
 internal IfTag(Template ownerTemplate)
     : base(ownerTemplate)
 {
     this.ElseIfs = new ElementCollection<IfConditionTag>();
 }
Exemple #12
0
 /// <summary>
 /// 克隆表达式
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <returns></returns>
 public IExpression Clone(Template ownerTemplate)
 {
     //常量表达式不会被模板外部修改.所以不进行数据克隆
     return(this);
 }
Exemple #13
0
        /// <summary>
        /// 使用特性方法预解析模板数据
        /// </summary>
        /// <param name="renderInstance"></param>
        /// <param name="renderMethod"></param>
        /// <param name="template"></param>
        internal static void PreRenderTemplateByAttributeMethod(string renderInstance, string renderMethod, Template template)
        {
            object render = GetRenderInstance(renderInstance);

            if (render != null)
            {
                //取得特性方法
                MethodInfo method = null;

                MethodInfo[] methods = render.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                foreach (MethodInfo m in methods)
                {
                    TemplateRenderMethodAttribute att = System.Attribute.GetCustomAttribute(m, typeof(TemplateRenderMethodAttribute)) as TemplateRenderMethodAttribute;
                    if (att != null)
                    {
                        if (renderMethod.Equals(m.Name, StringComparison.InvariantCultureIgnoreCase))
                        {
                            method = m;
                            break;
                        }
                    }
                }

                if (method != null)
                {
                    ParameterInfo[] pars = method.GetParameters();
                    if (pars.Length == 1 && pars[0].ParameterType == typeof(Template))
                    {
                        method.Invoke(method.IsStatic ? null : render, new object[] { template });
                    }
                }
            }
        }
Exemple #14
0
 /// <summary>
 /// 克隆当前元素到新的宿主模板
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <returns></returns>
 internal override Element Clone(Template ownerTemplate)
 {
     ForTag tag = new ForTag(ownerTemplate);
     base.CopyTo(tag);
     tag.Index = this.Index == null ? null : this.Index.Clone(ownerTemplate);
     return tag;
 }
Exemple #15
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ownerTemplate"></param>
 internal FunctionTag(Template ownerTemplate)
     : base(ownerTemplate)
 {
     this.FunctionArgs = new ElementCollection <IExpression>();
 }
        /// <summary>
        /// 克隆当前元素到新的宿主模板
        /// </summary>
        /// <param name="ownerTemplate"></param>
        /// <returns></returns>
        internal override Element Clone(Template ownerTemplate)
        {
            TemplateDocument tag = new TemplateDocument(this.DocumentConfig);

            //优先拷贝变量
            foreach (Variable var in this.Variables)
            {
                tag.Variables.Add(var.Clone(tag));
            }

            tag.Id = this.Id;
            tag.Name = this.Name;
            foreach (var att in this.Attributes)
            {
                tag.Attributes.Add(att.Clone(tag));
            }

            tag.Charset = this.Charset;
            tag.File = this.File;
            tag.fileDependencies = this.fileDependencies;
            tag.Visible = this.Visible;

            foreach (Element element in this.InnerElements)
            {
                Element item = element.Clone(tag);
                tag.AppendChild(item);

                if (element is Template && this.DocumentElement == element) tag.DocumentElement = (Template)item;
            }

            if (tag.DocumentElement == null) tag.DocumentElement = tag;
            return tag;
        }
 /// <summary>
 /// 解析字符串
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <param name="text"></param>
 private void ParseString(Template ownerTemplate, string text)
 {
     this.ParseString(ownerTemplate, ownerTemplate, text);
 }
Exemple #18
0
 /// <summary>
 /// 从模板中获取某个变量.如果不存在此变量则添加新的变量
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <param name="varName"></param>
 /// <returns></returns>
 internal static Variable GetVariableOrAddNew(Template ownerTemplate, string varName)
 {
     Variable var = ownerTemplate.Variables[varName];
     if (var == null)
     {
         var = new Variable(ownerTemplate, varName);
         ownerTemplate.Variables.Add(var);
     }
     return var;
 }
Exemple #19
0
 /// <summary>
 /// 开始解析标签数据
 /// </summary>
 /// <param name="ownerTemplate">宿主模板</param>
 /// <param name="container">标签的容器</param>
 /// <param name="tagStack">标签堆栈</param>
 /// <param name="text"></param>
 /// <param name="match"></param>
 /// <param name="isClosedTag">是否闭合标签</param>
 /// <returns>如果需要继续处理EndTag则返回true.否则请返回false</returns>
 public virtual bool ProcessBeginTag(Template ownerTemplate, Tag container, Stack <Tag> tagStack, string text, ref Match match, bool isClosedTag)
 {
     container.AppendChild(this);
     return(!isClosedTag);
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="documentElement"></param>
 /// <param name="container"></param>
 /// <param name="text"></param>
 /// <param name="documentConfig"></param>
 internal TemplateDocument(Template documentElement, Tag container, string text, TemplateDocumentConfig documentConfig)
 {
     this.DocumentConfig = documentConfig;
     this.AppendChild(documentElement);
     this.ChildTemplates.Add(documentElement);
     this.ParseString(documentElement, container, text);
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="documentElement"></param>
 /// <param name="text"></param>
 /// <param name="documentConfig"></param>
 internal TemplateDocument(Template documentElement, string text, TemplateDocumentConfig documentConfig) : this(documentElement, documentElement, text, documentConfig)
 {
 }
        /// <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;
            }
        }
 /// <summary>
 /// 解析字符串
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <param name="text"></param>
 private void ParseString(Template ownerTemplate, string text)
 {
     this.ParseString(ownerTemplate, ownerTemplate, text);
 }
Exemple #24
0
 /// <summary>
 /// 开始解析标签数据
 /// </summary>
 /// <param name="ownerTemplate">宿主模板</param>
 /// <param name="container">标签的容器</param>
 /// <param name="tagStack">标签堆栈</param>
 /// <param name="text"></param>
 /// <param name="match"></param>
 /// <param name="isClosedTag">是否闭合标签</param>
 /// <returns>如果需要继续处理EndTag则返回true.否则请返回false</returns>
 internal virtual bool ProcessBeginTag(Template ownerTemplate, Tag container, Stack<Tag> tagStack, string text, ref Match match, bool isClosedTag)
 {
     container.AppendChild(this);
     return !isClosedTag;
 }
Exemple #25
0
        /// <summary>
        /// 使用特性方法预解析模板数据
        /// </summary>
        /// <param name="renderInstance"></param>
        /// <param name="renderMethod"></param>
        /// <param name="template"></param>
        internal static void PreRenderTemplateByAttributeMethod(string renderInstance, string renderMethod, Template template)
        {
            object render = GetRenderInstance(renderInstance);
            if (render != null)
            {
                //取得特性方法
                MethodInfo method = null;

                MethodInfo[] methods = render.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                foreach (MethodInfo m in methods)
                {
                    TemplateRenderMethodAttribute att = System.Attribute.GetCustomAttribute(m, typeof(TemplateRenderMethodAttribute)) as TemplateRenderMethodAttribute;
                    if (att != null)
                    {
                        if (renderMethod.Equals(m.Name, StringComparison.InvariantCultureIgnoreCase))
                        {
                            method = m;
                            break;
                        }
                    }
                }

                if (method != null)
                {
                    ParameterInfo[] pars = method.GetParameters();
                    if (pars.Length == 1 && pars[0].ParameterType == typeof(Template))
                    {
                        method.Invoke(method.IsStatic ? null : render, new object[] { template });
                    }
                }
            }
        }
Exemple #26
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));
        }
Exemple #27
0
        /// <summary>
        /// 开始解析标签数据
        /// </summary>
        /// <param name="ownerTemplate">宿主模板</param>
        /// <param name="container">标签的容器</param>
        /// <param name="tagStack">标签堆栈</param>
        /// <param name="text"></param>
        /// <param name="match"></param>
        /// <param name="isClosedTag">是否闭合标签</param>
        /// <returns>如果需要继续处理EndTag则返回true.否则请返回false</returns>
        internal override bool ProcessBeginTag(Template ownerTemplate, Tag container, Stack<Tag> tagStack, string text, ref Match match, bool isClosedTag)
        {
            if (this.Variable == null && !this.Output) throw new ParserException(string.Format("{0}标签中如果未定义Output属性为true则必须定义var属性", this.TagName));
            if (this.Values.Count < 1) throw new ParserException(string.Format("{0}标签中缺少value属性", this.TagName));
            if (this.Values.Count > 1 && this.Format == null) throw new ParserException(string.Format("{0}标签如果已定义多个value属性,则也必须定义format属性", this.TagName));

            return base.ProcessBeginTag(ownerTemplate, container, tagStack, text, ref match, isClosedTag);
        }
        /// <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;
            }
        }
Exemple #29
0
 /// <summary>
 /// 克隆当前元素到新的宿主模板
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <returns></returns>
 internal override Element Clone(Template ownerTemplate)
 {
     SetTag tag = new SetTag(ownerTemplate);
     this.CopyTo(tag);
     tag.Variable = this.Variable == null ? null : this.Variable.Clone(ownerTemplate);
     tag.Output = this.Output;
     foreach (IExpression exp in this.Values)
     {
         tag.Values.Add((IExpression)(exp.Clone(ownerTemplate)));
     }
     return tag;
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="documentElement"></param>
 /// <param name="text"></param>
 /// <param name="documentConfig"></param>
 internal TemplateDocument(Template documentElement, string text, TemplateDocumentConfig documentConfig) : this(documentElement, documentElement, text, documentConfig) { }
Exemple #31
0
        /// <summary>
        /// 结束标签的解析
        /// </summary>
        /// <param name="ownerTemplate">模板宿主</param>
        /// <param name="container">元素容器</param>
        /// <param name="tagStack">标签堆栈</param>
        /// <param name="text"></param>
        /// <param name="match"></param>
        public 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));
            }
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ownerTemplate"></param>
 internal IncludeTag(Template ownerTemplate)
     : base(ownerTemplate)
 {
     this.Charset = ownerTemplate.Charset;
 }
Exemple #33
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ownerTemplate"></param>
 internal SetTag(Template ownerTemplate)
     : base(ownerTemplate)
 {
     this.Values = new ElementCollection <IExpression>();
 }
Exemple #34
0
        /// <summary>
        /// 根据前缀获取变量的模板所有者
        /// </summary>
        /// <param name="template"></param>
        /// <param name="prefix"></param>
        /// <returns>如果prefix值为null则返回template的根模板.如果为空值.则为template.如果为#则返回template的父模板.否则返回对应Id的模板</returns>
        internal static Template GetOwnerTemplateByPrefix(Template template, string prefix)
        {
            if (prefix == string.Empty) return template;               //前缀为空.则返回当前模板
            if (prefix == "#") return template.OwnerTemplate ?? template;   //前缀为#.则返回父模板(如果父模板不存在则返回当前模板)

            //取得根模板
            while (template.OwnerTemplate != null) template = template.OwnerTemplate;

            //如果没有前缀.则返回根模板.否则返回对应Id的模板
            return prefix == null ? template : template.GetChildTemplateById(prefix);
        }
Exemple #35
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ownerTemplate"></param>
 internal IfTag(Template ownerTemplate)
     : base(ownerTemplate)
 {
     this.ElseIfs = new ElementCollection <IfConditionTag>();
 }
Exemple #36
0
 /// <summary>
 /// 预解析模板数据
 /// </summary>
 /// <param name="renderInstance">模板解析器实例的配置</param>
 /// <param name="template">要解析处理的模板</param>
 internal static void PreRenderTemplate(string renderInstance, Template template)
 {
     ITemplateRender render = GetRenderInstance(renderInstance) as ITemplateRender;
     if (render != null) render.PreRender(template);
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="ownerTemplate"></param>
 internal DataReaderTag(Template ownerTemplate)
     : base(ownerTemplate)
 {
     this.Parameters = new ElementCollection <IExpression>();
 }
 /// <summary>
 /// 克隆表达式
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <returns></returns>
 public IExpression Clone(Template ownerTemplate)
 {
     //常量表达式不会被模板外部修改.所以不进行数据克隆
     return this;
 }
Exemple #39
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ownerTemplate"></param>
 internal IncludeTag(Template ownerTemplate)
     : base(ownerTemplate)
 {
     this.Charset = ownerTemplate.Charset;
 }
Exemple #40
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ownerTemplate"></param>
 internal SetTag(Template ownerTemplate)
     : base(ownerTemplate)
 {
     this.Values = new ElementCollection<IExpression>();
 }
Exemple #41
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <param name="text"></param>
 internal TextNode(Template ownerTemplate, string text)
     : base(ownerTemplate)
 {
     this.Text = text;
 }
Exemple #42
0
        /// <summary>
        /// 开始解析标签数据
        /// </summary>
        /// <param name="ownerTemplate">宿主模板</param>
        /// <param name="container">标签的容器</param>
        /// <param name="tagStack">标签堆栈</param>
        /// <param name="text"></param>
        /// <param name="match"></param>
        /// <param name="isClosedTag">是否闭合标签</param>
        /// <returns>如果需要继续处理EndTag则返回true.否则请返回false</returns>
        internal override bool ProcessBeginTag(Template ownerTemplate, Tag container, Stack<Tag> tagStack, string text, ref Match match, bool isClosedTag)
        {
            if (this.From == null) throw new ParserException(string.Format("{0}标签中缺少from属性", this.TagName));
            if (this.To == null) throw new ParserException(string.Format("{0}标签中缺少to属性", this.TagName));

            return base.ProcessBeginTag(ownerTemplate, container, tagStack, text, ref match, isClosedTag);
        }
Exemple #43
0
 /// <summary>
 /// 克隆当前元素到新的宿主模板
 /// </summary>
 /// <param name="ownerTemplate"></param>
 /// <returns></returns>
 internal override Element Clone(Template ownerTemplate)
 {
     return(new TextNode(ownerTemplate, this.Text));
 }
Exemple #44
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ownerTemplate"></param>
 internal ForTag(Template ownerTemplate)
     : base(ownerTemplate)
 {}
Exemple #45
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ownerTemplate"></param>
 public ImportTag(Template ownerTemplate)
     : base(ownerTemplate)
 {
 }