HTML Agility Pack - 选择特定节点后的节点

8
我在CodePlex的讨论中提出了问题,但我希望能在stackoverflow这里更快地得到答案。
所以,我使用HTML Agility Pack来解析C#中的HTML。 我有以下HTML结构:
<body>
   <p class="paragraph">text</p>
   <p class="paragraph">text</p>
   <p class="specific">text</p>
   <p class="paragraph">text</p>
   <p class="paragraph">text</p>
</body>

我需要获取所有在class为“specific”的p元素之后的class为“paragraph”的p元素。有什么方法可以实现吗?谢谢。
2个回答

6

使用Mark的示例中的.Class(如果不存在,请替换为适当的内容)

使用SkipWhile

例如,在LINQPad中,您可以从以下内容中获得5,6,7

int[] a = { 6, 5, 6 ,7 };
a.SkipWhile(x=>x!=6).Skip(1).Dump();

因此,根据 SelectNodes 返回的类型,可能是:

.SelectNodes( "/p" ).SkipWhile( p => p.Class != "specific" ).Skip(1)

或者

.SelectNodes( "/p" ).Cast<XX>().SkipWhile( p => p.Class != "specific" ).Skip(1)

(or, ugly version)

.SelectNodes( "/p" ).SkipWhile( p => ((XX)p).Class != "specific" ).Skip(1)

(或在某些情况下 - 如果您的表达式已经适当过滤,则不需要)
.SelectNodes( "/p" ).OfType<XX>().SkipWhile( p => p.Class != "specific" ).Skip(1)

编辑:我可能会创建一个扩展方法:

static class HapExtensions
{
    public IEnumerable<T> SkipUntilAfter( this IEnumerable<T> sequence, Predicate<T> predicate) {
        return sequence.SkipWhile( predicate).Skip(1);
       }
}

有没有人能搜索一下这方面的先前技术?有好的命名建议吗?

2

试试这个

bool latterDayParagraphs = false;
List<DocumentNode> nodes = new List<DocumentNode>();
foreach(var pElement in doc.DocumentNode.SelectNodes("/p"))
{
   if(pElement.Class != "paragraph") 
   {
      latterDayParagraphs = true;
      continue;
   }
   if(latterDayParagraphs)
   {
      nodes.Add(pElement);
   }
}

我猜你只是看了一眼问题,而没有真正读懂它。 :) 我使用HTML Agility Pack在C#中解析HTML,并且需要选择仅在class="specific"的p标签之后的class="paragraph"的p标签。 - morsanu
抱歉,希望这个答案更有用(你需要引用System.Linq)。 :) - Mark Dickinson
这将选择所有具有“paragraph”类的p标签。我只需要在具有class =“specific”的p标签之后的那些。 - morsanu
抱歉,这边时间还比较早,希望能有所帮助。很难想到更加优雅的方式。 - Mark Dickinson
没问题,伙计,我感谢你的帮助。这个解决方案在我脑海中浮现过,但我仍然希望不必使用它。也许会有更优雅的解决方案出现。如果没有,我会标记你的答案。 - morsanu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接