Удалите все пустые/ненужные узлы из HTML

Каким будет предпочтительный способ удалить все пустые и ненужные узлы? Например

<p></p> следует удалить, а <font><p><span><br></span></p></font> также следует удалить (поэтому тег br в этом случае считается ненужным)

Должен ли я использовать для этого какую-то рекурсивную функцию? Я думаю что-то вроде этого, может быть:

 RemoveEmptyNodes(HtmlNode containerNode)
 {
     var nodes = containerNode.DescendantsAndSelf().ToList();

      if (nodes != null)
      {
          foreach (HtmlNode node in nodes)
          {
              if (node.InnerText == null || node.InnerText == "")
              {
                   RemoveEmptyNodes(node.ParentNode);
                   node.Remove();
               }
           }
       }
  }

Но это явно не работает (исключение stackoverflow).


person Christer William Persson    schedule 20.07.2012    source источник
comment
Между пустым и ненужным есть огромная разница. Удаление пустых узлов может испортить макет.   -  person Marc Gravell    schedule 20.07.2012
comment
хорошо, так что лучше вообще не удалять пустые узлы?   -  person Christer William Persson    schedule 20.07.2012
comment
Наверное нет, нет. Другая причина: я был бы удивлен, если бы вы действительно намеревались считать элементы img пустыми.   -  person    schedule 20.07.2012
comment
Я вижу вашу точку зрения. Я думал, что было бы легко просто добавить исключения для изображений, например.   -  person Christer William Persson    schedule 20.07.2012


Ответы (1)


теги, которые не следует удалять, вы можете добавить имена в список, а узлы с атрибутами также не удаляются из-за containerNode.Attributes.Count == 0 (например, изображения)

static List<string> _notToRemove;

static void Main(string[] args)
{
    _notToRemove = new List<string>();
    _notToRemove.Add("br");

    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml("<html><head></head><body><p>test</p><br><font><p><span></span></p></font></body></html>");
    RemoveEmptyNodes(doc.DocumentNode);
}

static void RemoveEmptyNodes(HtmlNode containerNode)
{
    if (containerNode.Attributes.Count == 0 && !_notToRemove.Contains(containerNode.Name) && string.IsNullOrEmpty(containerNode.InnerText))
    {
        containerNode.Remove();
    }
    else
    {
        for (int i = containerNode.ChildNodes.Count - 1; i >= 0; i-- )
        {
            RemoveEmptyNodes(containerNode.ChildNodes[i]);
        }
    }
}
person user1519979    schedule 20.07.2012