如果要对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 " ) ) );
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);
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 >
< 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;
}
}
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
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 );
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
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 " ;
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 >
< 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节点后面加上了要添加的数据.