すでに使用しています
1 つのオプションは、出力を C# コードに解析し、それを XML にエンコードして、すべてのノードを作成string.Format("<{0}>", this.Name);
しstring.Format("</{0}>", this._name);
、その中間にすべての子ノードを再帰的に配置することです。
これを行った後、XML/HTML をクエリしてツリーを解析するためのツールを使用します。すでに何千人もの人々がクエリ セレクターと jQuery を使用して、ノード間の関係に基づいてツリー状の構造を解析しています。これは、TRegex や他の時代遅れで保守されていない Java ユーティリティよりもはるかに優れていると思います。
たとえば、これは最初の例に答えるものです。
var xml = CQ.Create(d.ToXml());
//this can be simpler with CSS selectors but I chose Linq since you'll probably find it easier
//Find joe, in our case the node that has the text 'Joe'
var joe = xml["*"].First(x => x.InnerHTML.Equals("Joe"));
//Find the last (deepest) element that answers the critiria that it has "Joe" in it, and has a VBD in it
//in our case the VP
var closestToVbd = xml["*"].Last(x => x.Cq().Has(joe).Has("VBD").Any());
Console.WriteLine("Closest node to VPD:\n " +closestToVbd.OuterHTML);
//If we want the VBD itself we can just find the VBD in that element
Console.WriteLine("\n\n VBD itself is " + closestToVbd.Cq().Find("VBD")[0].OuterHTML);
これがあなたの2番目の例です
//Now for NP closest to 'Shopping', find the element with the text 'shopping' and find it's closest NP
var closest = xml["*"].First(x => x.InnerHTML.Equals("shopping")).Cq()
.Closest("NP")[0].OuterHTML;
Console.WriteLine("\n\n NP closest to shopping is: " + closest);