예제 #1
0
 /// <summary>
 /// 检查元素是否为自结束标签
 /// </summary>
 /// <param name="tag">元素开始标签</param>
 /// <returns>是否为自结束标签</returns>
 protected virtual bool IsSelfCloseElement( HtmlBeginTag tag )
 {
   return HtmlSpecification.IsForbiddenEndTag( tag.TagName );
 }
예제 #2
0
 /// <summary>
 /// 检查元素是否为CDATA标签
 /// </summary>
 /// <param name="tag">元素开始标签</param>
 /// <returns>是否为CDATA标签</returns>
 protected virtual bool IsCDataElement( HtmlBeginTag tag )
 {
   return HtmlSpecification.IsCDataElement( tag.TagName );
 }
예제 #3
0
    /// <summary>
    /// 处理元素开始标签
    /// </summary>
    /// <param name="beginTag">开始标签信息</param>
    /// <returns>处理过程中所创建的元素对象,若不支持则返回 null</returns>
    protected virtual IHtmlElement ProcessBeginTag( HtmlBeginTag beginTag )
    {

      if ( HtmlSpecification == null )//当解析第一个开始标签时还没有找到 DTD 声明,则强行使用默认的 HTML 规范。
        SetHtmlSpecification( (HtmlDoctypeDeclaration) null );

      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.IsOptionalEndTag( element.Name ) )
        {
          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;
      }
    }