【问题标题】:Is there a way to get all text while keeping the links from linked words in one go with HTMLAgilityPack?有没有一种方法可以获取所有文本,同时使用 HTMLAgilityPack 一次性保留链接单词的链接?
【发布时间】:2012-07-30 01:07:10
【问题描述】:

我有一些混合了文本和链接的 html,我想提取文本与链接的单词一样,而不必删除链接,然后做一些疯狂的事情将其放回同一个地方。

HTML 如下所示:

<div id="i want what is inside here">
<h3>some text</h3>
<div>more text with a <a href="url">link</a></div>
<p>some more text<br />
<a href="url">another link</a> here...</p>
</div>

而我想要的输出是:

some text
more text with a <a href="url">link</a>
some more text
<a href="url">another link</a> here...

我知道如何使用 HTMLAgilityPack 提取文本最近我学到了很多关于如何使用祖先的新东西,在 xpath 和其他一些东西上的前面,这让我想知道:

是否可以使用 xpath 来获得上述所需的输出,或者我该怎么做?

如果没有可用的 xpath 条件,我正在考虑提取文本,然后提取链接并用链接替换文本上的链接内部文本匹配项(我认为不可靠)但这是我认为的一种方式那是可以做到的,你建议我怎么做?

【问题讨论】:

    标签: c# winforms .net-4.0 html-agility-pack


    【解决方案1】:

    XPath,即 XML 路径语言,是一种用于选择节点的查询语言 来自 XML 文档。

    您需要根据您的规则转换您的文档。您可以使用 xpath 选择应转换的节点,但不能使用 xpath 执行此转换。

    为此,您可以从最深到根节点遍历文档节点,如果这不是 &lt;a&gt; 标记,则将其替换为它的内部 HTML。

    幸运的是,AgilityPack 似乎按照在文档中找到的节点的顺序枚举节点。这意味着可以通过反转节点列表来检索必要的顺序。见:

    // getting the non-anchor nodes in the reversed order
    var nodes = doc.DocumentNode.SelectNodes("//*[name()!='a']")
        .Reverse()
        .ToList();
    
    // replacing with the inner html
    foreach (var node in nodes)
    {
        var replacement = doc.CreateTextNode(node.InnerHtml);
        node.ParentNode.ReplaceChild(replacement, node);
    }
    
    // and getting the output
    var output = doc.DocumentNode.OuterHtml;
    

    这会让你得到这样的东西:

    some text
    more text with a <a href='url'>link</a>
    some more text
    <a href='url'>another link</a> here...
    

    但请注意,在转换之后,文档变成了整个文本节点。如果您需要将其作为 HTML 片段使用,则必须从修改后的文档中创建一个新文档。

    【讨论】:

    • 这很简洁,至少你的方式可以防止很多我想使用的方式会出现的错误。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多