使用 HtmlAgilityPack 从两个 html 节点之间获取文本

Getting text from between two html nodes using HtmlAgilityPack

假设我有以下 HTML

<p id="definition">
    <span class="hw">emolument</span> \ih-MOL-yuh-muhnt\, <i>noun</i>:
    The wages or perquisites arising from office, employment, or labor
</p>

我想使用 HTMLC# 中的 AgilityPack 分别提取每个部分

我可以很容易地得到单词和单词class

var definition = doc.DocumentNode.Descendants()
    .Where(x => x.Name == "p" && x.Attributes["id"] == "definition")
    .FirstOrDefault();

string word = definition.Descendants()
    .Where(x => x.Name == "span")
    .FirstOrDefault().InnerText;

string word_class = definition.Descendants()
    .Where(x => x.Name == "i")
    .FirstOrDefault().InnerText;

但我如何获得发音或实际定义?这些落在节点之间,如果我使用 defintion.InnerText 我会在一个字符串中得到全部。有没有办法在 XPath 中做到这一点?

如何 select HtmlAgilityPack 中节点之间的文本?

Is there a way to do this in XPath perhaps?

是的 - 而且很简单。

您需要了解的关键概念是文本和子元素节点在 XML/HTML 中的组织方式 - 以及 XPath。

如果元素的文本内容被子元素打断,它们最终会出现在单独的文本节点中。您可以按位置访问各个文本节点。

只需在任何元素上使用 text() 即可检索所有子文本节点。将 //p/text() 应用于您显示的代码段会产生(各个结果由 ------- 分隔):

[EMPTY TEXT NODE, EXCEPT WHITESPACE]
-----------------------
\ih-MOL-yuh-muhnt\,
-----------------------
:
The wages or perquisites arising from office, employment, or labor

p 元素的第一个文本节点仅包含空格,因此这可能不是您想要的。 //p/text()[2] 检索

  \ih-MOL-yuh-muhnt\,

//p/text()[3]:

:
The wages or perquisites arising from office, employment, or labor
        HtmlNode text = doc.DocumentNode.Descendants().Where(x => x.Name == "p" && x.Id == "definition").FirstOrDefault();

        foreach (HtmlNode node in text.SelectNodes(".//text()"))
        {
            Console.WriteLine(node.InnerText.Trim());
        }

此输出将是:

  1. 薪酬
  2. \ih-MOL-yuh-muhnt\,
  3. 名词
  4. :
  5. 来自办公室、工作或劳动的工资或津贴

如果你想要2. \ih-MOL-yuh-muhnt\,结果。你需要这个。

HtmlNode a = text.SelectNodes(".//text()[2]").FirstOrDefault();