使用HtmlParser解析HTML ,C#版

如果要对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" >

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

<table name="table" >

<tr>

<td>HtmlParser</td>

<td><div >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" >

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

<table name="table" >

<tr>

<td>HtmlParser</td>

<td><div >HtmlParser</font>add a new node</div></td>

</tr>

</table>

</div>id为div_3的div节点后面加上了要添加的数据.