C# 使用HtnlAgilityPack从HTML文件解析

C# 使用HtnlAgilityPack从HTML文件解析,c#,html,html-parsing,html-agility-pack,C#,Html,Html Parsing,Html Agility Pack,我有一个由Oracle Reports生成的HTML(DTD HTML4.0过渡版)文件 以下是HTML文件的来源: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML><HEAD><META content="IE=5.0000" http-equiv="X-UA-Compatible"> <META http-equiv="Content-Ty

我有一个由Oracle Reports生成的HTML(DTD HTML4.0过渡版)文件

以下是HTML文件的来源:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><META content="IE=5.0000" http-equiv="X-UA-Compatible">

<META http-equiv="Content-Type" content="text/html; charset=windows-1251">
<META name="GENERATOR" content="MSHTML 11.00.9600.17801"></HEAD>
<BODY dir="LTR" bgcolor="#ffffff"> <!-- Created by Oracle Reports  --> 
<TABLE width="960" border="0" cellspacing="0" cellpadding="0">
  <TBODY>
  <TR valign="top">
    <TD height="9">
    <TD width="71" rowspan="3" colspan="3"><FONT face="Courier New" 
      size="1"><B><TT>Date</TT></B></FONT><BR>
    <TD>
    <TD width="89" rowspan="3" colspan="3"><FONT face="Courier New" 
      size="1"><B><TT>Target Number</TT></B></FONT>   
    <TD>
    <TD width="143" rowspan="3" colspan="7"><FONT face="Courier New" 
      size="1"><B><TT>Description</TT></B></FONT>   
    <TD colspan="11">
    <TD width="101" rowspan="3" colspan="4"><FONT face="Courier New" 
      size="1"><B><TT>Transaction </TT></B></FONT><BR><FONT face="Courier New" size="1"><B><TT>Sum</TT></B></FONT><BR>
    <TD colspan="2">
    <TD width="89" rowspan="3"><FONT face="Courier New" 
      size="1"><B><TT>Fee</TT></B></FONT>   
    <TD>
    <TD width="113" rowspan="3" colspan="4"><FONT face="Courier New" 
      size="1"><B><TT>Sum</TT></B></FONT>   
    <TD>
    <TD width="137" rowspan="3" colspan="2"><FONT face="Courier New" 
      size="1"><B><TT>Device </TT></B></FONT><BR><FONT face="Courier New" size="1"><B><TT>Id</TT></B></FONT><BR>
    <TD>
  <TR valign="top">
    <TD height="9">
    <TD>
    <TD>
    <TD colspan="3">
    <TD width="40" colspan="5"><FONT face="Courier New" 
      size="1"><B><TT>Reference</TT></B></FONT>   
    <TD colspan="3">
    <TD colspan="2">
    <TD>
    <TD>
    <TD>
  <TR valign="top">
    <TD height="9">
    <TD>
    <TD>
    <TD colspan="11">
    <TD colspan="2">
    <TD>
    <TD>
    <TD>
  <TR valign="top">
    <TD height="9">
    <TD width="71" rowspan="2" colspan="3"><FONT face="Courier New" 
      size="1"><TT>03/09/2015</TT></FONT>   
    <TD>
    <TD width="89" rowspan="2" colspan="3"><FONT face="Courier New" 
      size="1"><TT>4405641418</TT></FONT>   
    <TD>
    <TD width="143" rowspan="2" colspan="7"><FONT face="Courier New" 
      size="1"><TT>WWW.EXAMPLE.COM</TT></FONT>   
    <TD>
    <TD width="71" rowspan="2" colspan="9"><FONT face="Courier New" 
      size="1"><TT>524601231313</TT></FONT>   
    <TD>
    <TD width="101" rowspan="2" colspan="4"><FONT face="Courier New" 
      size="1"><TT> 1 087,00</TT></FONT>   
    <TD colspan="2">
    <TD width="89" rowspan="2"><FONT face="Courier New" 
      size="1"><TT>-26,09</TT></FONT>   
    <TD>
    <TD width="113" rowspan="2" colspan="4"><FONT face="Courier New" 
      size="1"><TT> 1 060,91</TT></FONT>   
    <TD>
    <TD width="137" rowspan="2" colspan="2"><FONT face="Courier New" 
      size="1"><TT>11055700</TT></FONT>   
    <TD>
  <TR valign="top">
    <TD height="9">
    <TD>
    <TD>
    <TD>
    <TD>
    <TD colspan="2">
    <TD>
    <TD>
    <TD>
  <TR>
    <TD height="5" colspan="43">
  <TR valign="top">
    <TD height="9">
    <TD width="71" rowspan="2" colspan="3"><FONT face="Courier New" 
      size="1"><TT>03/09/2015</TT></FONT>   
    <TD>
    <TD width="89" rowspan="2" colspan="3"><FONT face="Courier New" 
      size="1"><TT>4405641418</TT></FONT>   
    <TD>
    <TD width="143" rowspan="2" colspan="7"><FONT face="Courier New" 
      size="1"><TT>WWW.EXAMPLE.COM</TT></FONT>   
    <TD>
    <TD width="71" rowspan="2" colspan="9"><FONT face="Courier New" 
      size="1"><TT>524601231313</TT></FONT>   
    <TD>
    <TD width="101" rowspan="2" colspan="4"><FONT face="Courier New" 
      size="1"><TT> 55,00</TT></FONT>   
    <TD colspan="2">
    <TD width="89" rowspan="2"><FONT face="Courier New" 
      size="1"><TT>-1,32</TT></FONT>   
    <TD>
    <TD width="113" rowspan="2" colspan="4"><FONT face="Courier New" 
      size="1"><TT> 53,68</TT></FONT>   
    <TD>
    <TD width="137" rowspan="2" colspan="2"><FONT face="Courier New" 
      size="1"><TT>11055700</TT></FONT>   
    <TD>


</BODY></HTML>

如何访问
TT
标记?

如果它只是您想要的TT标记

HtmlNodeCollection tds = DocumentNode.SelectNodes("//body[@dir='LTR']//table//tbody//tr//td//tt");
应该给你所有的TT标签。 下次你能给我一个更短更具体的HTML文件吗。这一个没有表或tbody的结束标记

另外,我认为您必须将嵌套标记的选项设置为true,否则它将忽略td和tt标记

HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.OptionFixNestedTags=true;

如果它只是你想要的TT标签

HtmlNodeCollection tds = DocumentNode.SelectNodes("//body[@dir='LTR']//table//tbody//tr//td//tt");
应该给你所有的TT标签。 下次你能给我一个更短更具体的HTML文件吗。这一个没有表或tbody的结束标记

另外,我认为您必须将嵌套标记的选项设置为true,否则它将忽略td和tt标记

HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.OptionFixNestedTags=true;

我认为Kent发现了一些问题,您的文档有很多未关闭的
标记,这将在解析时引起问题。我想这是一个原因,即使是oracle也会强制在IE5兼容模式下进行渲染

在调试器中查看时,您将看到HtmlAgilityPack在文档末尾添加了大量关闭标记(在调试器中选中
doc.DocumentNode.OuterHtml
):

因此,为了找到您的
tt
标签,您必须求助于:

var tds = doc.DocumentNode.SelectNodes("//body//tr//td[@width=71 and @colspan=3]");
注意,我还简化了属性查找,例如,如果存在任何
callspan=33
width=171
,则
contains
将导致问题

您最好的操作可能是返回报告源并直接查询数据库。或者先关闭任何空的
,然后再进一步解析它们,从而修复文档

在加载文档之前,可以通过更改节点的ElementFlags来更改解析器,以不同方式检测
td
tr
,但我的尝试都遇到了与您已经遇到的相同的问题

HtmlNode.ElementsFlags.Remove("td");
HtmlNode.ElementsFlags.Add("td", HtmlElementFlag.Closed | HtmlElementFlag.Empty);
HtmlNode.ElementsFlags.Remove("tr");
HtmlNode.ElementsFlags.Add("tr", HtmlElementFlag.Closed);

我认为Kent发现了一些问题,您的文档有很多未关闭的
标记,这将在解析时引起问题。我想这是一个原因,即使是oracle也会强制在IE5兼容模式下进行渲染

在调试器中查看时,您将看到HtmlAgilityPack在文档末尾添加了大量关闭标记(在调试器中选中
doc.DocumentNode.OuterHtml
):

因此,为了找到您的
tt
标签,您必须求助于:

var tds = doc.DocumentNode.SelectNodes("//body//tr//td[@width=71 and @colspan=3]");
注意,我还简化了属性查找,例如,如果存在任何
callspan=33
width=171
,则
contains
将导致问题

您最好的操作可能是返回报告源并直接查询数据库。或者先关闭任何空的
,然后再进一步解析它们,从而修复文档

在加载文档之前,可以通过更改节点的ElementFlags来更改解析器,以不同方式检测
td
tr
,但我的尝试都遇到了与您已经遇到的相同的问题

HtmlNode.ElementsFlags.Remove("td");
HtmlNode.ElementsFlags.Add("td", HtmlElementFlag.Closed | HtmlElementFlag.Empty);
HtmlNode.ElementsFlags.Remove("tr");
HtmlNode.ElementsFlags.Add("tr", HtmlElementFlag.Closed);

+1关于作为问题一部分的小型且易于测试的复制请求。加上在调用
SelectNodes
+1之前对
HtmlDocument
对象执行的任何设置代码,作为问题的一部分,请求进行小型且易于测试的复制。加上调用
SelectNodes
之前对
HtmlDocument
对象执行的任何设置代码。请在下次需要帮助时提供帮助。请只显示html文件的准确和小的代表性,而不是在有大量冗余的地方。因为没人想看这些。下次你需要帮助的时候请。请只显示html文件的准确和小的代表性,而不是在有大量冗余的地方。因为没人想读这些。