2013-04-22 37 views
1

我有一个HtmlDocument可能或可能有一个合适的<head><body>节或可能只是一个html片段。无论哪种方式,我想通过一个函数来运行它,以确保它具有(更多)正确的html结构。用HtmlAgilityPack包装一个元素?

我知道,我可以检查它是否有身体,通过是否

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

为空。如果它没有body,我将如何将doc.DocumentNode的内容封装在<body>元素中,并将它分配回HtmlDocument

编辑:似乎有什么我想要做的混淆。在jQuery的条款:

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

基本上,如果没有身体的元素,周身放置一个元素。

+0

也许我是唯一一个,但我真的不明白你想要做什么。 – I4V 2013-04-22 20:49:08

+0

@ I4V - 请参阅编辑 – 2013-04-22 21:00:32

+0

如果没有body元素,请将body元素放在所有内容中,甚至包括'html'或'head'。 – I4V 2013-04-22 21:02:09

回答

3

你可以做这样的事情:

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; 
} 
+0

所以我不确定我是否理解 - 这会修改'HtmlDocument'现在包括''?我注意到你没有设置'doc.DocumentNode' – 2013-04-26 14:34:40

+0

是的,这就是你问我是否正确理解你的问题。 DOM是可读/写的,但不是根,除了执行Load(...)或LoadHtml(...)以外,不能设置doc.DocumentNode。 – 2013-04-26 15:16:07

+0

啊,我明白了,所以这听起来像我仍然可以用Load()来改变它,或者我可以修改我的方法来返回一个HtmlDocument。谢谢。 – 2013-04-26 17:36:45