/// <summary> /// 拷贝自身数据对某个新对象上 /// </summary> /// <param name="tag"></param> protected virtual void CopyTo(DMEWeb_Tag tag) { tag.Id = this.Id; tag.Name = this.Name; foreach (var att in this.Attributes) { tag.Attributes.Add(att.Clone(tag.OwnerTemplate)); } foreach (DMEWeb_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 virtual bool ProcessBeginTag(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Stack<DMEWeb_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> internal virtual void ProcessEndTag(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Stack<DMEWeb_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 (DMEWeb_ParserHelper.IsVariableTagStart(text, offset) && (match = DMEWeb_ParserRegex.VarTagRegex.Match(text, offset)).Success) //匹配到模板变量 { //构建文本节点 DMEWeb_ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, match.Index - charOffset); //构建模板变量 DMEWeb_ParserHelper.CreateVariableTag(ownerTemplate, container, match); } else if (DMEWeb_ParserHelper.IsTagStart(text, offset) && (match = DMEWeb_ParserRegex.TagRegex.Match(text, offset)).Success) //匹配到某种类型的标签 { //构建文本节点 DMEWeb_ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, match.Index - charOffset); //构建标签 DMEWeb_Tag tag = DMEWeb_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 (DMEWeb_ParserHelper.IsCloseTagStart(text, offset) && (match = DMEWeb_ParserRegex.EndTagRegex.Match(text, offset)).Success) //匹配到某个结束标签 { //构建文本节点 DMEWeb_ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, match.Index - charOffset); //取得标签名称 string name = match.Groups["tagname"].Value; //回滚标签堆栈.直到回滚到同名称元素的上级为此 while (tagStack.Count > 0) { DMEWeb_Tag popTag = tagStack.Pop(); if (name.Equals(popTag.TagName, StringComparison.InvariantCultureIgnoreCase)) break; if (!name.Equals(popTag.EndTagName, StringComparison.InvariantCultureIgnoreCase)) { //非匹配的结束标签.则模板有错 throw new DMEWeb_ParserException(string.Format("无效的结束标签,原期望的是{0}结束标签", popTag.EndTagName)); } } break; } else if (DMEWeb_ParserHelper.IsVTExpressionStart(text, offset)) { char s = DMEWeb_ParserHelper.ReadChar(text, offset + DMEWeb_ParserHelper.VTExpressionHead.Length); int startOffset = offset + DMEWeb_ParserHelper.VTExpressionHead.Length + 1; int lastOffset = text.IndexOf(s, offset + DMEWeb_ParserHelper.VTExpressionHead.Length + 1); if (lastOffset == -1) throw new DMEWeb_ParserException(string.Format("无法找到VT表达式[{0}{1}]的结束标记[{1}]", DMEWeb_ParserHelper.VTExpressionHead, s)); string code = text.Substring(startOffset, lastOffset - startOffset); if (code.Length > 0) { //构建文本节点 DMEWeb_ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, offset - charOffset); //解析表达式里的代码 new DMEWeb_TemplateDocument(ownerTemplate, container, code, ownerTemplate.OwnerDocument.DocumentConfig); } offset = lastOffset + 1; charOffset = offset; continue; } else if (DMEWeb_ParserHelper.IsCommentTagStart(text, offset)) { //构建文本节点 DMEWeb_ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, offset - charOffset); //找到注释的起始标记"<!--vt[",则直接查找结束标记"]-->" offset = text.IndexOf(DMEWeb_ParserHelper.CommentTagEnd, offset + DMEWeb_ParserHelper.CommentTagStart.Length); if (offset == -1) throw new DMEWeb_ParserException("无法找到注释的结束标记"); offset += DMEWeb_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 DMEWeb_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 override bool ProcessBeginTag(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Stack<DMEWeb_Tag> tagStack, string text, ref Match match, bool isClosedTag) { //判断标签的容器是否为IfTag标签 if (!(container is DMEWeb_IfTag)) throw new DMEWeb_ParserException(string.Format("未找到和{0}标签对应的{1}标签", this.TagName, this.EndTagName)); DMEWeb_IfTag ifTag = (DMEWeb_IfTag)container; if (ifTag.Else != null) throw new DMEWeb_ParserException(string.Format("{0}标签不能定义多个{1}标签", this.EndTagName, this.TagName)); //加入到If标签的Else节点 ifTag.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(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Stack<DMEWeb_Tag> tagStack, string text, ref Match match, bool isClosedTag) { if (this.Variable == null && !this.Output) throw new DMEWeb_ParserException(string.Format("{0}标签中如果未定义Output属性为true则必须定义var属性", this.TagName)); if (this.Field == null || string.IsNullOrEmpty(this.Field.Text)) throw new DMEWeb_ParserException(string.Format("{0}标签中缺少field属性", this.TagName)); if (this.Type == null) throw new DMEWeb_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="text"></param> /// <param name="offset"></param> /// <param name="length"></param> internal static void CreateTextNode(DMEWeb_Template ownerTemplate, DMEWeb_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 = DMEWeb_Utility.CompressText(content); } if (content.Length > 0) { //不建立空行文本节点 if(content.TrimStart('\r','\n','\t').Length != 0) container.AppendChild(new DMEWeb_TextNode(ownerTemplate, content)); } } }
/// <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(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Stack<DMEWeb_Tag> tagStack, string text, ref Match match, bool isClosedTag) { if (this.Variable == null) throw new DMEWeb_ParserException(string.Format("{0}标签中缺少var属性", this.TagName)); if (this.Connection == null) throw new DMEWeb_ParserException(string.Format("{0}标签中缺少connection属性", this.TagName)); if (this.CommandText == null) throw new DMEWeb_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> internal override bool ProcessBeginTag(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Stack<DMEWeb_Tag> tagStack, string text, ref Match match, bool isClosedTag) { //将自身加入到宿主的子模板列表中 ownerTemplate.ChildTemplates.Add(this); //加入到标签容器的元素列表中 container.AppendChild(this); if (!string.IsNullOrEmpty(this.File)) { //修正文件地址 this.File = DMEWeb_Utility.ResolveFilePath(this.Parent, this.File); if (System.IO.File.Exists(this.File)) { //增加到依赖文件列表 this.OwnerTemplate.AddFileDependency(this.File); //读取文件数据进行解析 new DMEWeb_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="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(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Stack<DMEWeb_Tag> tagStack, string text, ref Match match, bool isClosedTag) { if (this.Variable == null && !this.Output) throw new DMEWeb_ParserException(string.Format("{0}标签中如果未定义Output属性为true则必须定义var属性", this.TagName)); if (this.Type == null) throw new DMEWeb_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="text">模板文本数据</param> private void ParseString(DMEWeb_Template ownerTemplate, DMEWeb_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<DMEWeb_Tag> tagStack = new Stack<DMEWeb_Tag>(); tagStack.Push(container); try { while (offset < text.Length) { if (DMEWeb_ParserHelper.IsVariableTagStart(text, offset) && (match = DMEWeb_ParserRegex.VarTagRegex.Match(text, offset)).Success) //匹配到模板变量 { //构建文本节点 DMEWeb_ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, match.Index - charOffset); //构建模板变量 DMEWeb_ParserHelper.CreateVariableTag(ownerTemplate, container, match); } else if (DMEWeb_ParserHelper.IsTagStart(text, offset) && (match = DMEWeb_ParserRegex.TagRegex.Match(text, offset)).Success) //匹配到某种类型的标签 { //构建文本节点 DMEWeb_ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, match.Index - charOffset); //构建标签 DMEWeb_Tag tag = DMEWeb_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 (DMEWeb_ParserHelper.IsCloseTagStart(text, offset) && (match = DMEWeb_ParserRegex.EndTagRegex.Match(text, offset)).Success) //匹配到某个结束标签 { //取得标签名称 string name = match.Groups["tagname"].Value; //非匹配的结束标签.则模板有错 throw new DMEWeb_ParserException("无效的结束标签"); } else if (DMEWeb_ParserHelper.IsVTExpressionStart(text, offset)) { char s = DMEWeb_ParserHelper.ReadChar(text, offset + DMEWeb_ParserHelper.VTExpressionHead.Length); int startOffset = offset + DMEWeb_ParserHelper.VTExpressionHead.Length + 1; int lastOffset = text.IndexOf(s, offset + DMEWeb_ParserHelper.VTExpressionHead.Length + 1); if (lastOffset == -1) throw new DMEWeb_ParserException(string.Format("无法找到VT表达式\"{0}\"的结束标记", DMEWeb_ParserHelper.VTExpressionHead)); string code = text.Substring(startOffset, lastOffset - startOffset); if (code.Length > 0) { //构建文本节点 DMEWeb_ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, offset - charOffset); //解析表达式里的代码 new DMEWeb_TemplateDocument(ownerTemplate, container, code, ownerTemplate.OwnerDocument.DocumentConfig); } offset = lastOffset + 1; charOffset = offset; continue; } else if (DMEWeb_ParserHelper.IsCommentTagStart(text, offset)) { //构建文本节点 DMEWeb_ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, offset - charOffset); //找到注释的起始标记"<!--vt[",则直接查找结束标记"]-->" offset = text.IndexOf(DMEWeb_ParserHelper.CommentTagEnd, offset + DMEWeb_ParserHelper.CommentTagStart.Length); if (offset == -1) throw new DMEWeb_ParserException("无法找到注释的结束标记"); offset += DMEWeb_ParserHelper.CommentTagEnd.Length; charOffset = offset; continue; } //处理偏移位置 if (match != null && match.Success) { charOffset = offset = match.Index + match.Length; match = null; } else { offset++; } } //处理文本字符 DMEWeb_ParserHelper.CreateTextNode(ownerTemplate, container, text, charOffset, text.Length - charOffset); if (tagStack.Count > 1) { //堆栈里还有其它元素.则有错误 throw new DMEWeb_ParserException(string.Format("{0}标签未闭合", tagStack.Pop())); } } catch (DMEWeb_ParserException ex) { //如果错误中不包含行号与列号.则计算行号与列号 if (!ex.HaveLineAndColumnNumber && match != null && match.Success) { //获取当前出错时正在解析的模板文件 string file = string.Empty; DMEWeb_Tag tag = container; while (string.IsNullOrEmpty(file) && tag != null) { if (tag is DMEWeb_Template) { file = ((DMEWeb_Template)tag).File; } else if (tag is DMEWeb_IncludeTag) { file = ((DMEWeb_IncludeTag)tag).File; } tag = tag.Parent; } if (string.IsNullOrEmpty(file)) { throw new DMEWeb_ParserException(DMEWeb_Utility.GetLineAndColumnNumber(text, match.Index), match.ToString(), ex.Message); } else { throw new DMEWeb_ParserException(file, DMEWeb_Utility.GetLineAndColumnNumber(text, match.Index), match.ToString(), ex.Message); } } else { //继续抛出错误 throw; } } finally { //清空堆栈 tagStack.Clear(); tagStack = 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(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Stack<DMEWeb_Tag> tagStack, string text, ref Match match, bool isClosedTag) { if (this.Variable == null && !this.Output) throw new DMEWeb_ParserException(string.Format("{0}标签中如果未定义Output属性为true则必须定义var属性", this.TagName)); if (this.Values.Count < 1) throw new DMEWeb_ParserException(string.Format("{0}标签中缺少value属性", this.TagName)); if (this.Values.Count > 1 && this.Format == null) throw new DMEWeb_ParserException(string.Format("{0}标签如果已定义多个value属性,则也必须定义format属性", this.TagName)); return base.ProcessBeginTag(ownerTemplate, container, tagStack, text, ref match, isClosedTag); }
/// <summary> /// 注册当前呈现的标签 /// </summary> /// <param name="tag"></param> internal void RegisterCurrentRenderingTag(DMEWeb_Tag tag) { DMEWeb_TemplateDocument.CurrentRenderingDocument = tag == null ? null : tag.OwnerDocument; this.CurrentRenderingTag = tag; }
/// <summary> /// /// </summary> /// <param name="documentElement"></param> /// <param name="container"></param> /// <param name="text"></param> /// <param name="documentConfig"></param> internal DMEWeb_TemplateDocument(DMEWeb_Template documentElement, DMEWeb_Tag container, string text, DMEWeb_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(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Stack<DMEWeb_Tag> tagStack, string text, ref Match match, bool isClosedTag) { if (this.VarExpression == null) throw new DMEWeb_ParserException(string.Format("{0}标签中缺少var属性", this.TagName)); if (this.Values.Count == 0) throw new DMEWeb_ParserException(string.Format("{0}标签中缺少value属性", this.TagName)); //闭合标签则不进行数据处理 if (!isClosedTag) { container.AppendChild(this); } return !isClosedTag; }
/// <summary> /// 修正文件地址 /// </summary> /// <param name="tag"></param> /// <param name="fileName"></param> /// <returns></returns> internal static string ResolveFilePath(DMEWeb_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 DMEWeb_Template) { referPath = ((DMEWeb_Template)tag).File; } else if (tag is DMEWeb_IncludeTag) { referPath = ((DMEWeb_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(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Stack<DMEWeb_Tag> tagStack, string text, ref Match match, bool isClosedTag) { if (this.Values.Count == 0) throw new DMEWeb_ParserException(string.Format("{0}标签中缺少value属性", this.TagName)); //判断标签的容器是否为IfTag标签 if (!(container is DMEWeb_IfTag)) throw new DMEWeb_ParserException(string.Format("未找到和{0}标签对应的{1}标签", this.TagName, this.EndTagName)); DMEWeb_IfTag ifTag = (DMEWeb_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="tagStack">标签堆栈</param> /// <param name="text"></param> /// <param name="match"></param> /// <param name="isClosedTag">是否闭合标签</param> /// <returns>如果需要继续处理EndTag则返回true.否则请返回false</returns> internal override bool ProcessBeginTag(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Stack<DMEWeb_Tag> tagStack, string text, ref Match match, bool isClosedTag) { if (this.From == null) throw new DMEWeb_ParserException(string.Format("{0}标签中缺少from属性", this.TagName)); return base.ProcessBeginTag(ownerTemplate, container, tagStack, text, ref match, isClosedTag); }
/// <summary> /// 构建变量标签元素 /// </summary> /// <param name="ownerTemplate">宿主模板</param> /// <param name="container">标签的容器</param> /// <param name="match"></param> internal static DMEWeb_VariableTag CreateVariableTag(DMEWeb_Template ownerTemplate, DMEWeb_Tag container, Match match) { string prefix; DMEWeb_Variable variable = CreateVariable(ownerTemplate, match, out prefix); DMEWeb_VariableIdentity variableId = new DMEWeb_VariableIdentity(ownerTemplate, variable, prefix); //变量标签元素则需要缓存表达式的值 DMEWeb_VariableExpression varExp = CreateVariableExpression(variableId, match, true); DMEWeb_VariableTag tag = new DMEWeb_VariableTag(ownerTemplate, varExp); //解析属性列表 ParseElementAttributes(tag, match); container.AppendChild(tag); return tag; }