Обернуть элемент с помощью HtmlAgilityPack?

У меня есть HtmlDocument, который может иметь или может иметь правильный раздел <head> и <body> или может быть просто фрагментом html. В любом случае, я хочу запустить его через функцию, которая обеспечит (более) правильную структуру html.

Я знаю, что могу проверить, есть ли у него тело, посмотрев, есть ли у него тело.

doc.DocumentNode.SelectSingleNode("//body");

нулевой. Если у него нет тела, как мне обернуть содержимое doc.DocumentNode в элемент <body> и вернуть его в HtmlDocument?

Изменить. Кажется, есть некоторая путаница в том, что я хочу делать. В терминах jquery:

$doc = $(document);
if( !$doc.has('body') ) {
    $doc.wrapInner('body');
}

В принципе, если нет элемента body, поместите элемент body вокруг всего.


person George Mauer    schedule 22.04.2013    source источник
comment
Может, я один такой, но я не совсем понимаю, чем ты хочешь заниматься.   -  person I4V    schedule 23.04.2013
comment
if there is no body element, put a body element around everything. даже включая html или head?   -  person I4V    schedule 23.04.2013
comment
@ I4V - Предположим в контексте этого вопроса, что если нет элемента body, то также нет элемента html или head. Я могу проработать условия if самостоятельно, это фактическая упаковка, которую я не знаю, как это сделать.   -  person George Mauer    schedule 23.04.2013
comment
@ I4V - настоящий вопрос в том, как обернуть элементы в htmlagilitypack. Это не обязательно должен быть элемент body, это может быть что угодно.   -  person George Mauer    schedule 23.04.2013
comment
Разве вы не можете вставить фрагмент HTML-кода до / после, который объясняет, чего вы хотите достичь?   -  person AndyUK    schedule 06.04.2017


Ответы (1)


Вы можете сделать что-то вроде этого:

HtmlDocument doc = new HtmlDocument();
doc.Load(MyTestHtm);
HtmlNode body = doc.DocumentNode.SelectSingleNode("//body");
if (body == null)
{
    HtmlNode html = doc.DocumentNode.SelectSingleNode("//html");
    // we presume html exists

    body = CloneAsParentNode(html.ChildNodes, "body");
}


static HtmlNode CloneAsParentNode(HtmlNodeCollection nodes, string name)
{
    List<HtmlNode> clones = new List<HtmlNode>(nodes);
    HtmlNode parent = nodes[0].ParentNode;

    // create a new parent with the given name
    HtmlNode newParent = nodes[0].OwnerDocument.CreateElement(name);

    // insert before the first node in the selection
    parent.InsertBefore(newParent, nodes[0]);

    // clone all sub nodes
    foreach (HtmlNode node in clones)
    {
        HtmlNode clone = node.CloneNode(true);
        newParent.AppendChild(clone);
    }

    // remove all sub nodes
    foreach (HtmlNode node in clones)
    {
        parent.RemoveChild(node);
    }
    return newParent;
}
person Simon Mourier    schedule 23.04.2013
comment
Так что я не уверен, что понимаю - изменит ли это HtmlDocument, чтобы теперь включить <body>? Я заметил, что вы не устанавливаете doc.DocumentNode - person George Mauer; 26.04.2013
comment
Да, это то, что вы спросили, правильно ли я понял ваш вопрос. DOM читается / записывается, но не корень, вы не можете установить doc.DocumentNode иначе, чем выполняя Load (...) или LoadHtml (...). - person Simon Mourier; 26.04.2013
comment
Ах, понятно, похоже, я все еще могу изменить его с помощью Load () или изменить свой метод, чтобы он возвращал HtmlDocument. Спасибо. - person George Mauer; 26.04.2013
comment
Означает ли это, что решение могло бы или было бы другим, если бы оборачиваемый узел не был корневым? - person Max Carroll; 15.07.2020