/// <summary> /// 检查元素是否为CDATA标签 /// </summary> /// <param name="tag">元素开始标签</param> /// <returns>是否为CDATA标签</returns> protected virtual bool IsCDataElement(HtmlBeginTag tag) { return(HtmlSpecification.cdataTags.Contains(tag.TagName, StringComparer.OrdinalIgnoreCase)); }
/// <summary> /// 检查元素是否为CDATA标签 /// </summary> /// <param name="tag">元素开始标签</param> /// <returns>是否为CDATA标签</returns> protected virtual bool IsCDataElement(HtmlBeginTag tag) { return(HtmlSpecification.IsCDataElement(tag.TagName)); }
/// <summary> /// 处理元素开始标签 /// </summary> /// <param name="beginTag">开始标签信息</param> /// <returns>处理过程中所创建的元素对象,若不支持则返回 null</returns> protected virtual IHtmlElement ProcessBeginTag(HtmlBeginTag beginTag) { string tagName = beginTag.TagName; bool selfClosed = beginTag.SelfClosed; //检查是否为自结束标签,并作相应处理 if (IsSelfCloseElement(beginTag)) { selfClosed = true; } //检查是否为CData标签,并作相应处理 if (IsCDataElement(beginTag)) { Reader.EnterCDataMode(tagName.ToLowerInvariant()); } //检查父级是否可选结束标记,并作相应处理 { var element = CurrentContainer as IHtmlElement; if (element != null && HtmlSpecification.optionalCloseTags.Contains(element.Name, StringComparer.OrdinalIgnoreCase)) { if (ImmediatelyClose(tagName, element)) { ContainerStack.Pop(); } } } //处理所有属性 var attributes = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (var a in beginTag.Attributes) { string name = a.Name; string value = a.Value; if (value != null) { value = HtmlEncoding.HtmlDecode(value); } if (attributes.ContainsKey(name))//重复的属性名,只取第一个 { continue; } attributes.Add(name, value); } //创建元素 { var element = CreateElement(tagName, attributes); //加入容器堆栈 if (!selfClosed) { ContainerStack.Push(element); } return(element); } }
/// <summary> /// 检查元素是否为自结束标签 /// </summary> /// <param name="tag">元素开始标签</param> /// <returns>是否为自结束标签</returns> protected virtual bool IsSelfCloseElement(HtmlBeginTag tag) { return(HtmlSpecification.IsForbiddenEndTag(tag.TagName)); }