您的位置:首页 > Web前端 > HTML

使用HtmlParser解析HTML

2011-12-01 10:01 169 查看
如果要对HTML进行解析,提取HTML的数据或者修改HTML数据,HtmlParser是一个不错的选择.

使用HtmlParser可以解析本地和网络上的HTML数据:


Parser parser = new Parser( new Winista.Text.HtmlParser.Http.HttpProtocol(new Uri("uriString")));




Parser parser = new Parser( new Winista.Text.HtmlParser.Lex.Lexer( "HtmlString" ) );




System.IO.Stream stream = new System.IO.FileStream( "filePath" , System.IO.FileMode.Open );


Parser parser = new Parser( new Winista.Text.HtmlParser.Lex.Lexer( new Winista.Text.HtmlParser.Lex.Page( stream ,"charSet") ) );
还可以分析某些特定节点的数据,使用 NodeClassFilter 指定要分析的节点类型:


NodeFilter filter = new NodeClassFilter( typeof( Winista.Text.HtmlParser.Tags.Div ) );
使用Parser实例的Parse方法可以获得节点数组


NodeList nodeList = parser.Parse( null );




NodeList nodeList = parser.Parse( filter);
现在分析一下的一段HTML:


<div class="divCss" id="div_1">


<div name="div" class="divCss" id="div_2">div_2</div>


<table name="table" id="table_1">


<tr>


<td>HtmlParser</td>


<td><div id="div_3"><font color="red">HtmlParser</font></div></td>


</tr>


</table>


</div>

txtResult是显示分析处理后的数据,txtSource是读取HTML数据的文本框


//记录个节点的起始位置,避免重复处理


IList<int> start = new List<int>( );


protected void Button1_Click ( object sender , EventArgs e )






{


this.txtResult.Text = string.Empty;


Lexer lexer = new Lexer( this.txtSource.Text );


Parser parser = new Parser( lexer );


NodeFilter filter = new NodeClassFilter( typeof( Winista.Text.HtmlParser.Tags.Div ) );


NodeList nodeList = parser.Parse( null );


if ( nodeList.Count == 0 )


txtResult.Text = "没有符合要求的节点";


else






{


for ( int i = 0 ; i < nodeList.Count ; i++ )






{


paserData( nodeList[i] );


}


}


}


private ITag getTag ( INode node )






{


if ( node == null )


return null;


return node is ITag
? node as ITag : null;


}




private void paserData ( INode node)






{


ITag tag = getTag( node );


if ( tag != null && !tag.IsEndTag( ) && !start.Contains(tag.StartPosition))






{


object oId = tag.GetAttribute( "ID" );


object oName = tag.GetAttribute( "name" );


object oClass = tag.GetAttribute( "class" );


this.txtResult.Text += tag.TagName + ":\r\nID:" + oId + " Name:" + oName


+ " Class:" + oClass + " StartPosition:" + tag.StartPosition.ToString( ) + "\r\n";


start.Add( tag.StartPosition );


}


//子节点


if ( node.Children != null && node.Children.Count > 0 )






{


paserData( node.FirstChild );


}


//兄弟节点


INode siblingNode = node.NextSibling;


while ( siblingNode != null )






{


paserData( siblingNode );


siblingNode = siblingNode.NextSibling;


}


}
txtResult显示的数据为:


DIV:


ID:div_1 Name: Class:divCss StartPosition:0


DIV:


ID:div_2 Name:div Class:divCss StartPosition:34


TABLE:


ID:table_1 Name:table Class: StartPosition:90


TR:


ID: Name: Class: StartPosition:127


TD:


ID: Name: Class: StartPosition:136


TD:


ID: Name: Class: StartPosition:160


DIV:


ID:div_3 Name: Class: StartPosition:164


FONT:


ID: Name: Class: StartPosition:180



HtmlParser将我们指定的数据给分析出来了,现在来对要分析的数据进行一些修改:给没有name和class属性的指定属性:



object oId = tag.GetAttribute( "ID" );


object oName = tag.GetAttribute( "name" );


object oClass = tag.GetAttribute( "class" );




if ( oName == null )






{


oName = "name";


tag.SetAttribute( "name" , oName.ToString( ) );


}


if ( oClass == null )






{


oClass = "class";


tag.SetAttribute( "name" , oClass.ToString( ) );


}


this.txtResult.Text += tag.TagName + ":\r\nID:" + oId + " Name:" + oName


+ " Class:" + oClass + " StartPosition:" + tag.StartPosition.ToString( ) + "\r\n";


start.Add( tag.StartPosition );
txtResult显示的数据为:


DIV:


ID:div_1 Name:name Class:divCss StartPosition:0


DIV:


ID:div_2 Name:div Class:divCss StartPosition:34


TABLE:


ID:table_1 Name:table Class:class StartPosition:90


TR:


ID: Name:name Class:class StartPosition:127


TD:


ID: Name:name Class:class StartPosition:136


TD:


ID: Name:name Class:class StartPosition:160


DIV:


ID:div_3 Name:name Class:class StartPosition:164


FONT:


ID: Name:name Class:class StartPosition:180



HtmlParser实现了我们的目的,现在在给节点为DIV并且ID为div_3的节点添加一个子节点:



object oId = tag.GetAttribute( "ID" );


object oName = tag.GetAttribute( "name" );


object oClass = tag.GetAttribute( "class" );


if ( tag.TagName == "DIV" && tag.GetAttribute( "ID" ) == "div_3" )






{


INode newNode = new TextNode( "add a new node" );


tag.Children.Add( newNode );


}


this.txtResult.Text += tag.TagName + ":\r\nID:" + oId + " Name:" + oName


+ " Class:" + oClass + " StartPosition:" + tag.StartPosition.ToString( ) + "\r\n";
输出nodeList[0].ToHtml( ):


<div class="divCss" id="div_1">


<div name="div" class="divCss" id="div_2">div_2</div>


<table name="table" id="table_1">


<tr>


<td>HtmlParser</td>


<td><div id="div_3"><font color="red">HtmlParser</font>add a new node</div></td>


</tr>


</table>


</div>
id为div_3的div节点后面加上了要添加的数据.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: