我试图解析特定HTML字符串,这样我可以提取一组被打散线<br/>
断裂线。输入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>
使用更大的html文档中的div,我能够获得HTML ChildNodes
List<HtmlNode> nodes = htmlDoc.DocumentNode
.Descendants("div")
.Where(x => x.Attributes.Contains("class") &&
x.Attributes["class"].Value.Contains("PlainText")).ToList();
我不完全确定从哪里开始,我想阅读所有文本,直到我看到两个分隔线并停止?
编辑
我看着的childNodes nodes
在Visual Studio中运行时检查,发现里面居然是不是两个consectuive <br/>
线,但单断线和#text
与它的innerHTML存在标签\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";
}
哪个回报
请注意在两个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));
我不使用内联lambda只是为了提高可读性。条件的工作方式如下:
br
节点,如果不是 - 请获取当前节点br
节点,如果不是 - 获取当前节点结果: