2012-05-29 14 views
5

Wordで作成された大量のヘルプ文書があり、これはさらに大量の未熟なHTM文書を生成するために使用されました。 C#とこのライブラリを使用して、アプリケーションの任意のポイントでこのファイルの1つのセクションだけを取得して表示します。セクションは、次のように分割されていますHtml Agility Packを使用して2つのHTMLタグ間でコンテンツを取得する

<!--logical section starts here --> 
<div> 
<h1><span style='mso-spacerun:yes'></span><a name="_Toc325456104">Section A</a></h1> 
</div> 
<div> Lots of unnecessary markup for simple formatting... </div> 
..... 
<!--logical section ends here --> 

<div> 
<h1><span style='mso-spacerun:yes'></span><a name="_Toc325456104">Section B</a></h1> 
</div> 

論理的に話すが、aタグ内のセクション名を持つH1があります。私は別のh1に出会うまで、divを含む外側からすべてを選択し、そのdivを除外したいと思います。各セクション名が複数の子を持つh1<a>タグに位置しています

  • (約6各)
  • 論理セクションは、これらのコメントは、実際の文書には存在しないコメント
  • でマークされ

私の試み:

var startNode = helpDocument.DocumentNode.SelectSingleNode("//h1/a[contains(., '"+sectionName+"')]"); 
//go up one level from the a node to the h1 element 
startNode=startNode.ParentNode; 

//get the start index as the index of the div containing the h1 element 
int startNodeIndex = startNode.ParentNode.ChildNodes.IndexOf(startNode); 

//here I am not sure how to get the endNode location. 
var endNode =?; 

int endNodeIndex = endNode.ParentNode.ChildNodes.IndexOf(endNode); 

//select everything from the start index to the end index 
var nodes = startNode.ParentNode.ChildNodes.Where((n, index) => index >= startNodeIndex && index <= endNodeIndex).Select(n => n); 

Sine私はこれに関するドキュメントを見つけることができませんでしたが、私はどのように私のスタートノードから次のh1要素に到達できるのか分かりません。任意の提案をいただければ幸いです。

答えて

5

H1タグがセクションヘッドにのみ表示されると仮定していますが、これを実行すると思います。そうでない場合は、子孫のWhereを追加して、見つかったH1ノード上の他のフィルタをチェックできます。これには、セクション名を持つ次のdivになるまで、divのすべての兄弟が含まれます。

private List<HtmlNode> GetSection(HtmlDocument helpDocument, string SectionName) 
{ 
    HtmlNode startNode = helpDocument.DocumentNode.Descendants("div").Where(d => d.InnerText.Equals(SectionName, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); 
    if (startNode == null) 
     return null; // section not found 

    List<HtmlNode> section = new List<HtmlNode>(); 
    HtmlNode sibling = startNode.NextSibling; 
    while (sibling != null && sibling.Descendants("h1").Count() <= 0) 
    { 
     section.Add(sibling); 
     sibling = sibling.NextSibling; 
    } 

    return section; 
} 
+0

ニース。ドキュメントのセクション名に複数のdivがあるため、フィルタを少し変更しなければなりませんでした。私は 'HtmlNode startNode = helpDocument.DocumentNode.Descendants(" h1 ")を使って終わりました。(d => d.InnerText.Contains(SectionName))。FirstOrDefault();'そしてそこから親ノードまで移動します。それの残りは完全に働いた。ありがとう – Rondel

+0

優秀。私はとてもうれしいです。 –

0

実際、h1タグの周りにdivがありますか? 「はい」の場合、これは機能するはずです。

helpDocument.DocumentNode.SelectSingleNode("//h1/a[contains(@name, '"+sectionName+"')]/ancestor::div"); 

また、あなたのHtmlに応じてSelectNodesと動作します。このよう は:

helpDocument.DocumentNode.SelectNodes("//h1/a[starts-with(@name,'_Toc')]/ancestor::div"); 

ああ、これをテストしながら、私はすべてが正常に動作し、属性名に変更したら、メソッドが含まれている中で私のために働いていないものはドットがあったことに気づきました。

+0

かなりです。私は 'h1'タグを囲むdivを望みますが、次の' h1'タグの周囲のdivまですべての未来のdivs/spanを取得したいと思います。しかし、ありがとう。 – Rondel

関連する問題