/// <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; }
/// <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; }
/// <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.VarExpression == null) throw new ParserException(string.Format("{0}标签中缺少var属性", this.TagName)); if (this.Values.Count == 0) throw new ParserException(string.Format("{0}标签中缺少value属性", this.TagName)); //闭合标签则不进行数据处理 if (!isClosedTag) { container.AppendChild(this); } return !isClosedTag; }
/// <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) throw new ParserException(string.Format("{0}标签中缺少var属性", this.TagName)); if (this.Connection == null) throw new ParserException(string.Format("{0}标签中缺少connection属性", this.TagName)); if (this.CommandText == null) throw new ParserException(string.Format("{0}标签中缺少commandtext属性", this.TagName)); return base.ProcessBeginTag(ownerTemplate, container, tagStack, text, ref match, isClosedTag); }
/// <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="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; } }
/// <summary> /// 拷贝自身数据对某个新对象上 /// </summary> /// <param name="tag"></param> protected virtual void CopyTo(Tag tag) { tag.Id = this.Id; tag.Name = this.Name; foreach (var att in this.Attributes) { tag.Attributes.Add(att.Clone(tag.OwnerTemplate)); } foreach (Element element in this.InnerElements) { tag.AppendChild(element.Clone(tag.OwnerTemplate)); } }
/// <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.Method == null || string.IsNullOrEmpty(this.Method.Text)) throw new ParserException(string.Format("{0}标签中缺少method属性", this.TagName)); return base.ProcessBeginTag(ownerTemplate, container, tagStack, text, ref match, isClosedTag); }
/// <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.Values.Count == 0) throw new ParserException(string.Format("{0}标签中缺少value属性", this.TagName)); //判断标签的容器是否为IfTag标签 if (!(container is IfTag)) throw new ParserException(string.Format("未找到和{0}标签对应的{1}标签", this.TagName, this.EndTagName)); IfTag ifTag = (IfTag)container; //判断此条件是否带var属性.如果不带则设置为if的条件 if (this.VarExpression == null) this.VarExpression = ifTag.VarExpression; //加入到If标签的ElseIf队列 ifTag.AddElseCondition(this); return true; }
/// <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="tag"></param> internal void RegisterCurrentRenderingTag(Tag tag) { TemplateDocument.CurrentRenderingDocument = tag == null ? null : tag.OwnerDocument; this.CurrentRenderingTag = 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) { if (this.Variable == null && !this.Output) throw new ParserException(string.Format("{0}标签中如果未定义Output属性为true则必须定义var属性", this.TagName)); if (this.Type == null) throw new ParserException(string.Format("{0}标签中缺少type属性或type属性值未知", this.TagName)); //if (this.Type != ServerDataType.Random // && this.Type != ServerDataType.Time // && this.Type != ServerDataType.Request // && this.Type != ServerDataType.Environment // && this.Item == null) throw new ParserException(string.Format("当{0}标签type=\"{1}\"时必须设置item属性值", this.TagName, this.Type)); return base.ProcessBeginTag(ownerTemplate, container, tagStack, text, ref match, isClosedTag); }
/// <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> /// <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; }
/// <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.TagId == null && this.File == null) throw new ParserException(string.Format("{0}标签中必须定义tagid或file属性", this.TagName)); bool flag = base.ProcessBeginTag(ownerTemplate, container, tagStack, text, ref match, isClosedTag); return flag; }
/// <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)); }
/// <summary> /// 构建文本节点元素 /// </summary> /// <param name="ownerTemplate">宿主模板</param> /// <param name="container">标签的容器</param> /// <param name="text"></param> /// <param name="offset"></param> /// <param name="length"></param> internal static void CreateTextNode(Template ownerTemplate, Tag container, string text, int offset, int length) { if (length > 0) { string content = text.Substring(offset, length); if (ownerTemplate.OwnerDocument.DocumentConfig != null && ownerTemplate.OwnerDocument.DocumentConfig.CompressText) { //压缩文本 content = Utility.CompressText(content); } if (content.Length > 0) { //不建立空行文本节点 if(content.TrimStart('\r','\n','\t').Length != 0) container.AppendChild(new TextNode(ownerTemplate, content)); } } }
/// <summary> /// 构建变量标签元素 /// </summary> /// <param name="ownerTemplate">宿主模板</param> /// <param name="container">标签的容器</param> /// <param name="match"></param> internal static VariableTag CreateVariableTag(Template ownerTemplate, Tag container, Match match) { string prefix; Variable variable = CreateVariable(ownerTemplate, match, out prefix); VariableIdentity variableId = new VariableIdentity(ownerTemplate, variable, prefix); //变量标签元素则需要缓存表达式的值 VariableExpression varExp = CreateVariableExpression(variableId, match, true); VariableTag tag = new VariableTag(ownerTemplate, varExp); //解析属性列表 ParseElementAttributes(tag, match); container.AppendChild(tag); return tag; }
/// <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="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) { //将自身加入到宿主的子模板列表中 ownerTemplate.ChildTemplates.Add(this); //加入到标签容器的元素列表中 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(this, System.IO.File.ReadAllText(this.File, this.Charset), ownerTemplate.OwnerDocument.DocumentConfig); } } //非闭合标签则查找结束标签 if (!isClosedTag) { this.ProcessEndTag(this, this, tagStack, text, ref match); } //因为已处理EndTag.所以不需要外部继续再处理 return false; }
/// <summary> /// 修正文件地址 /// </summary> /// <param name="tag"></param> /// <param name="fileName"></param> /// <returns></returns> internal static string ResolveFilePath(Tag tag, string fileName) { if (!string.IsNullOrEmpty(fileName) && fileName.IndexOf(":") == -1 && !fileName.StartsWith("\\\\")) { string referPath = string.Empty; while (string.IsNullOrEmpty(referPath) && tag != null) { if (tag is Template) { referPath = ((Template)tag).File; } else if (tag is IncludeTag) { referPath = ((IncludeTag)tag).File; } tag = tag.Parent; } if (!string.IsNullOrEmpty(referPath)) { fileName = Path.Combine(Path.GetDirectoryName(referPath), fileName); } fileName = Path.GetFullPath(fileName); } return fileName; }
/// <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) throw new ParserException(string.Format("{0}标签中缺少var属性", this.TagName)); if (this.Type == null || string.IsNullOrEmpty(this.Type.Text)) throw new ParserException(string.Format("{0}标签中缺少type属性", this.TagName)); return base.ProcessBeginTag(ownerTemplate, container, tagStack, text, ref match, isClosedTag); }
/// <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); }
/// <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 (string.IsNullOrEmpty(this.Container) && string.IsNullOrEmpty(this.Id)) throw new ParserException(string.Format("{0}标签中必须定义id或者container属性", this.TagName)); if (!string.IsNullOrEmpty(this.Container)) { var conTag = this.OwnerDocument.GetChildTagById(this.Container) as PanelTag; if (conTag == null) throw new ParserException(string.Format("{0}标签中Container属性定义的“{1}”<vt:panel>标签不存在", this.TagName, this.Container)); conTag.Panels.Add(this); } bool flag = base.ProcessBeginTag(ownerTemplate, container, tagStack, text, ref match, isClosedTag); return flag; }