2012-05-29 29 views
5

Tenemos un documento de ayuda absolutamente masivo creado en Word y esto se usó para generar un documento HTM aún más masivo y poco pesado. Usando C# y esta biblioteca, solo quiero tomar y mostrar una sección de este archivo en cualquier punto de mi aplicación. Las secciones se dividen así:Obtener contenido entre dos etiquetas HTML usando Html Agility Pack

<!--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> 

Lógicamente hablando, no es una H1 con un nombre de sección en una etiqueta a. Quiero seleccionar todo desde el div que contiene el exterior hasta que encuentre otro h1 y excluya ese div.

  • Cada Nombre de la sección se encuentra en una etiqueta <a> bajo un h1 que tiene varios hijos (alrededor de 6 cada uno)
  • La sección lógica está marcado con comentarios
  • Estos comentarios no existen en el documento actual

Mi intento:

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 No he podido encontrar documentación sobre esto, no sé cómo puedo pasar de mi nodo de inicio al siguiente elemento h1. Cualquier sugerencia sera apreciada.

Respuesta

5

Creo que esto lo hará, aunque asume que las etiquetas H1 solo aparecen en los encabezados de sección. Si ese no es el caso, puede agregar un Where en los descendientes para buscar otros filtros en cualquier nodo H1 que encuentre. Tenga en cuenta que esto incluirá a todos los hermanos del div que encuentre hasta que llegue al siguiente con un nombre de sección.

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

Agradable. Tuve que modificar ligeramente el filtro porque tenía varios divs con los nombres de las secciones en el documento. Terminé usando 'HtmlNode startNode = helpDocument.DocumentNode.Descendants (" h1 "). Where (d => d.InnerText.Contains (SectionName)). FirstOrDefault();' y moviéndome hacia el nodo primario desde allí. El resto funcionó perfectamente. Gracias – Rondel

+0

Excelente. Estoy tan contento de que funcionó. –

0

Entonces, lo que realmente quiere como resultado es el div alrededor de la etiqueta h1? En caso afirmativo, entonces esto debería funcionar.

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

también trabaja con SelectNodes dependiendo de su HTML. De esta manera:

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

Ah, y mientras se prueba esto me di cuenta de que la cosa no funciona para mí fue el punto en el método contains, una vez que lo cambio al nombre de atributo todo funciona bien.

+0

No del todo. Quiero el div que rodea la etiqueta 'h1', pero también quiero obtener todos los divs/spans futuros hasta el div circundante de la próxima etiqueta' h1'. Gracias sin embargo. – Rondel

Cuestiones relacionadas