Rodear el nodo existente con otro nodo con Agility Pack

c# html-agility-pack

Pregunta

¿Cómo haría para rodear todas las tablas con un nodo <div class="overflow"></div> ? Esto al parecer no lo hace:

if (oldElement.Name == "table")
{
    HtmlDocument doc = new HtmlDocument();
    HtmlNode newElement = doc.CreateElement("div");
    newElement.SetAttributeValue("class", "overflow");
    newElement.AppendChild(oldElement);
    oldElement.ParentNode.ReplaceChild(newElement, oldElement);
}

No le pasa nada a las tablas cuando intento ese código. Pero si uso:

if (oldElement.Name == "table")
{
    oldElement.Remove();
}

Todas las tablas se eliminan, así que estoy seguro de que estoy accediendo a los nodos correctos.

Respuesta aceptada

Puede que sea un poco feo, pero podría editar el atributo InnerHtml del nodo oldElement.ParentNode así:

if (oldElement.Name == "table")
{
    oldElement.ParentNode.InnerHtml = "\r\n<div class=\"overflow\">\r\n"
        + oldElement.OuterHtml +
        "\r\n</div>\r\n";
}

Tampoco parece que pudieras editar el atributo OuterHtml de oldElement (por lo que primero debes obtener el ParentNode). El HtmlAgilityPack dice que puede obtener / establecer OuterHtml, pero VS2010 me dijo que es una propiedad de solo lectura.

Editar

Estaba jugando con un código para resolver esto y vi que oldElement.ParentNode convierte en el nodo <div> después de AppendChild() . La solución que encontré es hacer otro HtmlNode al comienzo del bloque if para mantener al padre y luego llamar a ReplaceChild() en ese nodo al final:

if (oldElement.Name == "table")
{
    HtmlNode theParent = oldElement.ParentNode;

    HtmlDocument doc = new HtmlDocument();
    HtmlNode newElement = doc.CreateElement("div");
    newElement.SetAttributeValue("class", "overflow");
    newElement.AppendChild(oldElement);

    theParent.ReplaceChild(newElement, oldElement);
}

Respuesta popular

Echa un vistazo a CsQuery , un puerto C # de jQuery. Esto se puede lograr fácilmente. Primero carga el documento:

CQ doc = CQ.CreateFromFile(..)  // or
CQ doc = CQ.CreateFromUrl(..)   // or
CQ doc = CQ.Create(string)

Cree la estructura para envolver, aquí hay cuatro formas diferentes de hacerlo.

var wrap = CQ.CreateFragment("<div class='overflow'></div>");   // or

// you can pass HTML as a selector as in jQuery. The property indexer for a CQ
// object is the default method, same as $(..)

var wrap = doc["<div class='overflow'></div>"];   // or

var wrap = doc["<div />"].AddClass("overflow");  // or

// creates an element directly, sames as browser DOM methods

var wrap = doc.Document.CreateElement("div");
wrap.ClassName="overflow";

Envuelve todas las mesas con la estructura:

doc["table"].Wrap(wrap);          // or use longhand for the Select method

doc.Select("table").Wrap(wrap);   

Render el documento completo a una cadena:

string html = doc.Render();


Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué