/// <summary> /// 验证html标签 /// </summary> /// <param name="node"></param> /// <param name="tagName"></param> /// <param name="tag"></param> protected virtual void ValidateAction(IElement node, string tagName, PolicyHtmlTag tag) { var parentNode = node.Parent; #region 过滤样式 if ("style".Equals(tagName, StringComparison.OrdinalIgnoreCase)) { try { node.InnerHtml = CssFilter.Filters(node.InnerHtml); } catch { parentNode.RemoveChild(node); } } #endregion #region 过滤属性 for (int currentAttributeIndex = 0; currentAttributeIndex < node.Attributes.Length; currentAttributeIndex++) { var attribute = node.Attributes[currentAttributeIndex]; string name = attribute.Name, _value = attribute.Value; var attr = Policy.AllowedAttribute(name, tag); #region 如果是白名单之外的属性移除掉 if (attr == null) { node.RemoveAttribute(name); currentAttributeIndex--; continue; } #endregion #region 元素内嵌样式 if ("style".Equals(name, StringComparison.OrdinalIgnoreCase)) { try { attribute.Value = CssFilter.Filters(_value); if (string.IsNullOrWhiteSpace(attribute.Value)) { node.RemoveAttribute(name); currentAttributeIndex--; } } catch { node.RemoveAttribute(name); currentAttributeIndex--; } continue; } #endregion //如果未能通过验证,将执行指定的操作 if (!Policy.ValidateAttribute(attr, _value)) { switch (attr.OnInvalid) { case PolicyHtmlAttributeOnInvalid.RemoveTag: //删除当前的元素并退出函数 parentNode.RemoveChild(node); return; case PolicyHtmlAttributeOnInvalid.FilterTag: //删除当前节点,但保留其有效的子节点 PromoteChildren(node); return; default: //删除当前的属性,指针往回调 node.RemoveAttribute(attr.Name); currentAttributeIndex--; break; } } } #endregion //过滤当前元素的子节点 FiltersTags(node.ChildNodes); }