Wir haben ein absolut umfangreiches Hilfedokument, das in Word erstellt wurde, und es wurde verwendet, um ein noch massiveres und unwürdigeres HTM-Dokument zu erstellen. Mit C # und dieser Bibliothek möchte ich nur einen Abschnitt dieser Datei an einem beliebigen Punkt in meiner Anwendung abrufen und anzeigen. Abschnitte sind wie folgt aufgeteilt:
<!--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>
Logischerweise gibt es ein H1
mit einem Abschnittsnamen in einem a
Tag. Ich möchte alles aus dem äußeren mit div auswählen, bis ich auf ein anderes h1
und dieses div ausschließe.
<a>
-Tag unter einem h1
das mehrere <a>
Elemente enthält (jeweils etwa 6). Mein Versuch:
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);
Ich konnte keine Dokumentation dazu finden, ich weiß nicht, wie ich von meinem Startknoten zum nächsten h1-Element gelangen kann. Irgendwelche Vorschläge würden geschätzt werden.
Ich denke, das wird es tun, obwohl angenommen wird, dass H1-Tags nur in Abschnittsköpfen erscheinen. Wenn dies nicht der Fall ist, können Sie ein Wo auf den Nachkommen hinzufügen, um nach anderen Filtern auf allen gefundenen H1-Knoten zu suchen. Beachten Sie, dass dies alle Geschwister des gefundenen Div enthält, bis es zum nächsten mit einem Sektionsnamen kommt.
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;
}
Also, was Sie wirklich wollen, ist das Div um den h1-Tag? Wenn ja, dann sollte das funktionieren.
helpDocument.DocumentNode.SelectSingleNode("//h1/a[contains(@name, '"+sectionName+"')]/ancestor::div");
Funktioniert auch mit SelectNodes
abhängig von Ihrem HTML. So was:
helpDocument.DocumentNode.SelectNodes("//h1/a[starts-with(@name,'_Toc')]/ancestor::div");
Oh, und während ich dies testete, bemerkte ich, dass das Ding, das nicht für mich funktionierte, der Punkt in der contains-Methode war, sobald ich es zum name-Attribut ändere, funktioniert alles gut.