Utilizando htmlagility, estoy buscando nodos de texto en una estructura dom que consiste en una selección.
<select>
<option>
one
</option>
<option>
two
</option>
</select>
Esos nodos padres parecen ser los
<select>
en lugar de un
<option>
¿Por qué?
using System.IO;
using System.Linq;
using HtmlAgilityPack;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Foo.Test
{
[TestClass]
public class HtmlAgilityTest
{
[TestMethod]
public void TestTraverseTextNodesInSelect()
{
var html = "<select><option>one</option><option>two</option></select>";
var doc = new HtmlDocument();
doc.Load(new StringReader(html));
var elements = doc.DocumentNode.Descendants().Where(n=>n.Name == "#text");
Assert.AreEqual(2, elements.Count());
Assert.AreEqual("select", elements.ElementAt(0).ParentNode.Name);
Assert.AreEqual("select", elements.ElementAt(1).ParentNode.Name);
}
}
}
Esto se debe a que HtmlAgilityPack soltó cerrar la etiqueta <option>
por defecto . HAP ve tu HTML de esta manera:
Console.WriteLine(doc.DocumentNode.OuterHtml);
//result :
//<select><option>one<option>two</select>
Y como se mencionó en la pregunta vinculada anterior, puede modificar ese comportamiento llamando a la siguiente línea antes de iniciar el HtmlDocument
:
HtmlNode.ElementsFlags.Remove("option");
[TestMethod]
public void TestTraverseTextNodesInSelect()
{
HtmlNode.ElementsFlags.Remove("option");
var html = "<select><option>one</option><option>two</option></select>";
var doc = new HtmlDocument();
doc.Load(new StringReader(html));
var elements = doc.DocumentNode.Descendants().Where(n=>n.Name == "#text");
Assert.AreEqual(2, elements.Count());
Assert.AreEqual("select", elements.ElementAt(0).ParentNode.Name);
Assert.AreEqual("select", elements.ElementAt(1).ParentNode.Name);
}
Puedes intentarlo con esto.
En la biblioteca tiene así. Necesitas quitarlo. por defecto, AgilityPack está configurado para tratar las etiquetas de opción como vacías.
ElementsFlags.Add("option", HtmlElementFlag.Empty);