/// <summary> /// 收集子标签。 /// </summary> /// <param name="tag">指定一个标签实例。</param> /// <param name="index">指定标签索引。</param> /// <returns>Tag</returns> private Tag CollectForTag(Tag tag, ref int index) { if (tag.IsClosed) return tag; if (string.Compare(tag.Name, "if", true) == 0) tag = new TagIf(tag.Line, tag.Col, tag.AttributeValue("test")); Tag collectTag = tag; for (index++; index < _Elements.Count; index++) { Element elem = _Elements[index]; if (elem is Text) collectTag.InnerElements.Add(elem); else if (elem is Expression) collectTag.InnerElements.Add(elem); else if (elem is Tag) { Tag innerTag = (Tag)elem; if (string.Compare(innerTag.Name, "else", true) == 0) { if (collectTag is TagIf) { ((TagIf)collectTag).FalseBranch = innerTag; collectTag = innerTag; } else throw new ParseException("else 标签必须包含在 if 或 elseif 之内。", innerTag.Line, innerTag.Col); } else if (string.Compare(innerTag.Name, "elseif", true) == 0) { if (collectTag is TagIf) { Tag newTag = new TagIf(innerTag.Line, innerTag.Col, innerTag.AttributeValue("test")); ((TagIf)collectTag).FalseBranch = newTag; collectTag = newTag; } else throw new ParseException("elseif 标签位置不正确。", innerTag.Line, innerTag.Col); } else collectTag.InnerElements.Add(CollectForTag(innerTag, ref index)); } else if (elem is TagClose) { TagClose tagClose = (TagClose)elem; if (string.Compare(tag.Name, tagClose.Name, true) == 0) return tag; throw new ParseException("没有为闭合标签 " + tagClose.Name + " 找到合适的开始标签。", elem.Line, elem.Col); } else throw new ParseException("无效标签: " + elem.GetType().ToString(), elem.Line, elem.Col); } throw new ParseException("没有为开始标签 " + tag.Name + " 找到合适的闭合标签。", tag.Line, tag.Col); }
/// <summary> /// 处理 Set 标签。 /// </summary> /// <param name="tag">包含 set 方法的标签实例。</param> protected void ProcessTagSet(Tag tag) { Expression expName = tag.AttributeValue("name"); if (expName == null) throw new TemplateRuntimeException("Set 找不到必须的属性:name", tag.Line, tag.Col); Expression expValue = tag.AttributeValue("value"); if (expValue == null) throw new TemplateRuntimeException("Set 找不到必须的属性:value", tag.Line, tag.Col); string name = this.EvalExpression(expName).ToString(); if (!Smart.Framework.Utility.Converter.IsValidVariableName(name)) throw new TemplateRuntimeException("指定了非法的标签名:'" + name + "'", expName.Line, expName.Col); object value = this.EvalExpression(expValue); this.SetValue(name, value); }
/// <summary> /// 处理 foreach 标签。 /// </summary> /// <param name="tag">包含 foreach 语句的标签实例。</param> protected void ProcessForEach(Tag tag) { Expression expCollection = tag.AttributeValue("collection"); if (expCollection == null) throw new TemplateRuntimeException("Foreach 找不到必须的属性:collection", tag.Line, tag.Col); object collection = this.EvalExpression(expCollection); if (!(collection is IEnumerable)) throw new TemplateRuntimeException("foreach 的 Collection 必须可以转换为 enumerable", tag.Line, tag.Col); Expression expVar = tag.AttributeValue("var"); if (expCollection == null) throw new TemplateRuntimeException("Foreach 找不到必须的属性:var", tag.Line, tag.Col); object varObject = this.EvalExpression(expVar); if (varObject == null) varObject = "foreach"; string varname = varObject.ToString(); Expression expIndex = tag.AttributeValue("index"); string indexname = null; if (expIndex != null) { object obj = this.EvalExpression(expIndex); if (obj != null) indexname = obj.ToString(); } IEnumerator ienum = ((IEnumerable)collection).GetEnumerator(); int index = 0; while (ienum.MoveNext()) { index++; object value = ienum.Current; _Variables[varname] = value; if (indexname != null) _Variables[indexname] = index; this.ProcessElements(tag.InnerElements); } }
/// <summary> /// 处理标签。 /// </summary> /// <param name="tag">指定一个标签实例。</param> protected void ProcessTag(Tag tag) { string name = tag.Name.ToLowerInvariant(); try { switch (name) { case "template": break; case "else": this.ProcessElements(tag.InnerElements); break; case "apply": object val = this.EvalExpression(tag.AttributeValue("template")); this.ProcessTemplate(val.ToString(), tag); break; case "foreach": this.ProcessForEach(tag); break; case "for": this.ProcessFor(tag); break; case "set": this.ProcessTagSet(tag); break; default: this.ProcessTemplate(tag.Name, tag); break; } } catch (TemplateRuntimeException ex) { this.DisplayError(ex); } catch (Exception ex) { this.DisplayError("处理标记时出错:'" + name + "': " + ex.Message, tag.Line, tag.Col); } }
/// <summary> /// 处理 for 标签。 /// </summary> /// <param name="tag">包含 for 语句的标签实例。</param> protected void ProcessFor(Tag tag) { Expression expFrom = tag.AttributeValue("from"); if (expFrom == null) throw new TemplateRuntimeException("For 找不到必须的属性:from", tag.Line, tag.Col); Expression expTo = tag.AttributeValue("to"); if (expTo == null) throw new TemplateRuntimeException("For 找不到必须的属性:to", tag.Line, tag.Col); Expression expIndex = tag.AttributeValue("index"); if (expIndex == null) throw new TemplateRuntimeException("For 找不到必须的属性:index", tag.Line, tag.Col); object obj = this.EvalExpression(expIndex); string indexName = obj.ToString(); int start = Convert.ToInt32(this.EvalExpression(expFrom)); int end = Convert.ToInt32(this.EvalExpression(expTo)); for (int index = start; index <= end; index++) { SetValue(indexName, index); this.ProcessElements(tag.InnerElements); } }