【问题标题】:HtmlAgilityPack remove childnode of childnodeHtmlAgilityPack 删除子节点的子节点
【发布时间】:2016-01-11 23:13:53
【问题描述】:

我有一个包含类似这样的字符串:

string text = "<p>test <span> <font> here </font> </span> try</p><p> <font> try 2</font> </p>"

我需要的是过滤这样的东西:

将文本保留在 P 中 删除跨度和内容(字体和文本) 如果直接父级不是 Span*,则将 Text 保留在字体内

我拥有的是:

StringBuilder sbtexttoCorrect = new StringBuilder();
HtmlDocument html = new HtmlDocument();
html.LoadHtml(textToFormat);
var nodes = html.DocumentNode.SelectNodes("//p");

foreach (var line in nodes)
{
   if (line.Name =="SPAN")
   {
      line.RemoveAllChildren();
      line.Remove();
   }
}
foreach (var txt in nodes)
{
sbtexttoCorrect.Append(txt.InnerText);
}

但是最后的 sbtexttoCorrect 仍然得到 span 的子字体。即使使用 Removechild 和他自己的 Remove。

我错过了什么?

注意:在另一个帖子上有人告诉我:

 foreach (var line in nodes.Select(node => node.ChildNodes.Where(
     childNode => childNode.Name != "span"))
                    .Select(
                        textNodes => textNodes.Aggregate(String.Empty, (current, node) => current + node.InnerText)))
        {

            sbtexttoCorrect.Append(line);
        }

但是我不明白所有的语法,所以我想重写我自己的尝试,而且它也没有一直工作,它仍然在 Span 中获取 Font 中的文本。

注意 2 我找不到关于 Agilty Pack 规格的任何文档。如果有人知道在哪里可以找到它,我想了解更多关于这个库的信息。

编辑真正的 HTML 要复杂得多,有许多我不知道的 childNode,它们可以是 TD 或 DIV,唯一真正确定的是当有span 我需要跳过他的内容和他的 childNode

【问题讨论】:

  • 我编辑了我的答案。它现在独立地删除它们在 html 中的哪个级别的所有跨度

标签: c# html-agility-pack


【解决方案1】:

我在您的代码中看到了这些问题:

  • 您将跨度视为大写,而 HtmlAgilityPack 将其视为小写 => 您的 if 块永远不会命中
  • 你只循环 p 元素(而不是 p 元素的子元素)=>你的 if 块永远不会命中

根据您的其他说明,这应该可行:

  • 它使用 XPath 选择所有跨度(因此应该适用于大写和小写)
  • 它删除了跨度
  • 它清除所有 html 元素(如 here 所示)

    string text = "<p>test <SPAN> <font> here </font> </SPAN> try</p><p><table> <tr><td><span>test</span></td></tr></table><font> try 2</font> </p>";
    StringBuilder sbtexttoCorrect = new StringBuilder();
    HtmlDocument html = new HtmlDocument();
    html.LoadHtml(text);
    var nodes = html.DocumentNode.SelectNodes("//span");
    
    foreach (var node in nodes)
    {
        node.Remove();
    }
    
    foreach (var node in html.DocumentNode.DescendantsAndSelf())
    {
        if (!node.HasChildNodes)
        {
            string t = node.InnerText;
            if (!string.IsNullOrEmpty(t))
                sbtexttoCorrect.AppendLine(t);
        }
    }
    

【讨论】:

  • 好吧,我使用的字符串可能有节点用大写,但我也用小写尝试过。在您的情况下,不会采用 内的 内的文本,因为您没有跳过 子节点?
  • 是的,这不是您想要的吗? "Keep Text inside P Remove Span and content (font and text) Keep Text inside font if its direct parent is not a Span*"
  • 是的,这就是我想要的,但这意味着在我得到一张桌子的情况下,他不会遍历所有桌子并观察所有孩子,他只会遍历两个第一级子节点?
  • 试了之后,还是得到了他不应该在的Span的Font里面的Text
  • 我发布的代码给出了 "test try try 2" 。你说你没有得到相同的输出?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-09
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多