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