Surround existing node with another node with Agility Pack

c# html-agility-pack

Question

How would you go about encircling every table with a<div class="overflow"></div> node? It seems that this is ineffective:

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);
}

When I use that code, the tables remain unchanged. But if I employ:

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

Since all tables have been deleted, I can be certain that I'm accessing the right nodes.

1
4
7/18/2012 11:46:30 AM

Accepted Answer

You might just alter the oldElement's InnerHtml property, albeit it could be a little unsightly. Like this: ParentNode node

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

Additionally, it doesn't seem that you could modify the oldElement's OuterHtml property (which is why you have to get the ParentNode first). In contrast to what the HTML Agility Pack claims, Visual Studio 2010 informed me that OuterHtml is a read-only property.

Edit

To solve this, I was experimenting with some code when I saw thatoldElement.ParentNode takes on the<div> after nodeAppendChild() is known as. The answer I discovered is to create anotherHtmlNode holding the parent at the beginning of the if block before callingReplaceChild() relating to the last node:

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);
}
7
7/18/2012 2:35:12 PM

Popular Answer

Examine CsQuery, a jQuery transfer to C#. This is a simple task to do. First, open the file:

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

Here are four ways you may create the framework for your wrapping.

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";

Wrap each table in the following structure:

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

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

Turn the whole thing into a string:

string html = doc.Render();


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow