【问题标题】:HtmlAgilityPack set node InnerTextHtmlAgilityPack 设置节点 InnerText
【发布时间】:2012-01-06 15:32:35
【问题描述】:

我想用另一个文本替换 HTML 标记的内部文本。 我正在使用 HtmlAgilityPack
我用这段代码提取所有文本

HtmlDocument doc = new HtmlDocument();
doc.Load("some path")

foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//text()[normalize-space(.) != '']")) {
    // How to replace node.InnerText with some text ?
}

但是 InnerText 是只读的。如何将文本替换为其他文本并将其保存到文件中?

【问题讨论】:

  • 元素的内部文本是所有子标签内部文本的组合。是否要将所有子标签替换为文本节点?
  • @YuriyRozhovetskiy 我想用一些文本替换每个元素文本确实我想将网站翻译成另一种语言。我想从页面中提取所有文本,然后翻译、替换和保存。
  • 奇怪的是,XML 文档说这个属性 Gets or Sets the text between the start and end tags of the object. 但随后只提供了一个 get 方法...

标签: c# parsing html-parsing html-agility-pack


【解决方案1】:

试试下面的代码。它选择所有没有子节点的节点并过滤掉脚本节点。也许您需要添加一些额外的过滤。除了您的 XPath 表达式之外,此表达式还寻找叶节点并过滤掉 <script> 标记的文本内容。

var nodes = doc.DocumentNode.SelectNodes("//body//text()[(normalize-space(.) != '') and not(parent::script) and not(*)]");
foreach (HtmlNode htmlNode in nodes)
{
    htmlNode.ParentNode.ReplaceChild(HtmlTextNode.CreateNode(htmlNode.InnerText + "_translated"), htmlNode);
}

【讨论】:

  • 非常感谢。如何将翻译后的 html 覆盖到以前的文件?我从文件加载节点/
  • 明白了! Doc.save .. 非常感谢 :]
  • 如果可能的话,请描述一下我的代码 XPath 和你的有什么区别?
  • 只是为了进一步说明将文本设置到节点的正确方法是将HtmlTextNode替换为使用HtmlTextNode.CreateNode("text here...")创建的新方法
  • 我知道这是一个老问题,但你在这里救了我的命,谢谢!
【解决方案2】:

奇怪,但我发现 InnerHtml 不是只读的。当我尝试这样设置时

aElement.InnerHtml = "sometext";

InnerText的值也改为"sometext"

【讨论】:

  • 但是您也有可能更改 html 标签
  • InnerHtml 不是只读的。内文是。关于 InnerText 不是只读的,文档似乎是错误的。
  • 虽然InnerHtml 支持get/set,但在某些情况下,它并不总是会实际更改文档内容。如果设置好了,再看文档的OuterHtml,内容是不会一直变的。
  • 在此评论(2021.01.04)的那一刻,它只支持获取操作
【解决方案3】:

HtmlTextNode 类有一个 Text 属性* 非常适合此目的。

这是一个例子:

var textNodes = doc.DocumentNode.SelectNodes("//body/text()").Cast<HtmlTextNode>();
foreach (var node in textNodes)
{
    node.Text = node.Text.Replace("foo", "bar");
}

如果我们有一个HtmlNode 想要更改其直接文本,我们可以执行以下操作:

HtmlNode node = //...
var textNode = (HtmlTextNode)node.SelectSingleNode("text()");
textNode.Text = "new text";

或者我们可以使用node.SelectNodes("text()"),以防它有多个。


*不要与只读的InnerText 属性混淆。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2017-07-06
    相关资源
    最近更新 更多