Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用HTML AgilityPack通过特征线解析HTML_C#_Parsing_Html Agility Pack - Fatal编程技术网

C# 使用HTML AgilityPack通过特征线解析HTML

C# 使用HTML AgilityPack通过特征线解析HTML,c#,parsing,html-agility-pack,C#,Parsing,Html Agility Pack,我正在尝试解析一个特定的HTML字符串,以便提取一组由换行符分隔的行。输入HTML如下所示: <div class="PlainText"> DATE: 2013-10-28 20:00:43 -0500 <br/> Item 1: Text1 <br/> Item 1: Text1 <br/> Item 1: Text1 <br/> Item 1: Text1 <br/> <br/> /

我正在尝试解析一个特定的HTML字符串,以便提取一组由

换行符分隔的行。输入HTML如下所示:

<div class="PlainText">
  DATE: 2013-10-28 20:00:43 -0500 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  <br/> //Notice this has two break lines, i would like to stop after seeing two consecutive break lines.
</div>
我不完全确定从这里走到哪里,我想阅读所有文本,直到看到两条特征线并停止

编辑

我在Visual Studio runtime inspector中查看了childNodes
节点
,注意到实际上没有两行连续的

行,而是一行换行符和一个
#text
标记,其内部HTML是
\n
新行字符


像这样的东西应该可以用

[Test]
public void Test()
{
    var x = ReadTillTwoBr(GetDivClass()).ToList();
}

public HtmlNode GetDivClass()
{
    var html = @"<html><div class=""PlainText"">
            DATE: 2013-10-28 20:00:43 -0500 <br/>
            Item 1: Text1 <br/>
            Item 1: Text1 <br/>
            Item 1: Text1 <br/>
            Item 1: Text1 <br/>
            <br   /> //Notice this has two break lines, i would like to stop after seeing two consecutive break lines.
            Item 3
        </div></html>";
    var doc = new HtmlDocument();
    doc.LoadHtml(html);

    return doc.DocumentNode
                .Descendants("div").First(x => x.Attributes.Contains("class") &&
                                                x.Attributes["class"].Value.Contains("PlainText"));

}

public IEnumerable<string> ReadTillTwoBr(HtmlNode node)
{
    var nonEmptyNodes =
        node.ChildNodes.Except(node.ChildNodes.Where(f => f.Name == "#text" && String.IsNullOrWhiteSpace(f.InnerHtml)))
            .ToList();

    foreach (var n in nonEmptyNodes)
    {
        if (IsBr(n) && IsBr(n.NextSibling))
        {
            yield break;
        }

        if (n.Name == "#text")
        {
            yield return n.InnerText.Trim();
        }
    }
}

public bool IsBr(HtmlNode n)
{
    return n != null && n.NodeType == HtmlNodeType.Element && n.Name == "br";
}
[测试]
公开无效测试()
{
var x=ReadTillTwoBr(GetDivClass()).ToList();
}
公共HtmlNode GetDivClass()
{
var html=@”
日期:2013-10-28 20:00:43-0500
第1项:文本1
第1项:文本1
第1项:文本1
第1项:文本1

x.Attributes.Contains(“类”)&& x、 属性[“类”].Value.Contains(“纯文本”); } 公共IEnumerable ReadTillTwoBr(HtmlNode节点) { 非空节点= node.ChildNodes.Except(node.ChildNodes.Where(f=>f.Name==“#text”&&String.IsNullOrWhiteSpace(f.InnerHtml))) .ToList(); foreach(非空节点中的var n) { 如果(IsBr(n)和&IsBr(n.NextSibling)) { 屈服断裂; } 如果(n.Name==“#文本”) { 屈服返回n.InnerText.Trim(); } } } 公共布尔IsBr(HtmlNode n) { 返回n!=null&&n.NodeType==HtmlNodeType.Element&&n.Name==“br”; }
返回

注意,它在两个br之后没有返回注释

编辑:


我删除了空的
#text
值,因为当在最后两个
br
标记之间有一个换行符时,实际上会得到一个带有换行符的
#text
标记。我认为这就是新行混淆的地方。

您可以使用XPath
/div[@class='PlainText']
获取所需的div节点。在从div获取子节点时,还可以检查下一个同级节点:

HtmlDocument doc = new HtmlDocument();
doc.Load("index.html");
Func<HtmlNode, bool> notTwoBrakes = 
    n => (n.Name != "br" || n.NextSibling != null && n.NextSibling.Name != "br");
var nodes = doc.DocumentNode.SelectNodes("//div[@class='PlainText']")
               .Select(div => div.ChildNodes.TakeWhile(notTwoBrakes));
HtmlDocument doc=新的HtmlDocument();
doc.Load(“index.html”);
Func notTwoBrakes=
n=>(n.Name!=“br”| | n.NextSibling!=null&&n.NextSibling.Name!=“br”);
var nodes=doc.DocumentNode.SelectNodes(“//div[@class='PlainText']”)
.Select(div=>div.ChildNodes.TakeWhile(nottworbrakes));
我不使用内联lambda只是为了可读性。条件是这样的:

<div class="PlainText">
  DATE: 2013-10-28 20:00:43 -0500 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  <br/> //Notice this has two break lines, i would like to stop after seeing two consecutive break lines.
</div>
  • 检查下一个节点是否为空,如果为空,则取当前节点
  • 检查下一个节点是否为
    br
    节点,如果不是-取当前节点
  • 检查当前节点是否为
    br
    节点,如果不是-取当前节点
  • 否则停止获取子节点
结果:


真的吗?我看到两个br标记,使用您发布的相同示例。输入HTML有两个br标记,但正如您从屏幕截图和我在调试
节点
返回时检查得到的一样,它们之间有一个
#text
标记,内部HTML仅读取换行符。您关心换行符吗?您的问题仅说明br标记。如果换行是一个问题,你可以在它上面使用一个字符串修剪不,我不关心换行,我想我会提到它,因为从技术上讲,它不是两个紧跟在一起的
br
标记,而是介于HTML兼容性包之间的换行将换行视为文本字段的一部分(因为换行只是文本,它们不是标记),所以他们真的没什么区别不知道是谁投了反对票,但我可以在这里使用一些相同的想法来检查只有一个换行符的元素
\n
。在那里,我更新了它,使它读取所有的文本,直到找到两个连续的br/标记。@Warz这有帮助吗?还是我误解了你的要求?是的,这很有帮助,我现在正在运行测试,看看你提到的文本标记是否可以忽略,并且在运行
isBr
时是否被忽略。顺便说一句,谢谢。我一直没有得到任何回报,而且我已经修改了几次剧本。屈服中断从未发生,并返回所有子节点。在第二次
br
#text
返回后,我仍然使用
nottworbrakes
检查?@Warz刚刚验证,一切正常。也许您还有其他一些条件来停止读取数据。在找到双断点后,我的查询停止读取每个div中的节点。您可以在调试器屏幕截图中看到它