c# - 仅获取此节点的 InnerText,不包括子节点

标签 c# html string html-agility-pack

因为我还不太熟悉 XPath,所以我更喜欢使用 HtmlAgilityPack 的 LINQ。我认为这是我需要 XPath 解决方案的情况之一。所以我需要你的帮助。

考虑这个简化的 HTML 片段:

<td><b>Billing informations:</b>
    <table>
        <tr>
            <td style="color: #757575; padding-left: 10px; padding-bottom: 20px;">
                Invoice-Number:1534753<br />Transactioncode: 1WF772582A4041717
            </td>
        </tr>
    </table>
</td>

这是一个更大的 HTML 页面的一部分,但它展示了我遇到的问题。我需要提取 Invoice-NumberTransactionCode。有时文本在一个跨度中,有时像这里一样直接在单元格中。所以我需要一种适用于这两种情况的方法。

我已经试过了:

var invoiceCell = doc.DocumentNode.Descendants("td")
    .FirstOrDefault(cell => cell.InnerText.Contains("Invoice-Number"));
if (invoiceCell != null)
{
    string text = invoiceCell.InnerText;
    // use string methods to extract both values
}

问题是 invoiceCell.InnerText 返回最外层单元格的 InnerText,而不是包含 Invoice-Number 的单元格。所以 text 也包含“Billing informations”:

Billing informations:



                Invoice-Number:1534753Transactioncode: 1WF772582A4041818

虽然在这种情况下我可以使用字符串方法或正则表达式来提取这两个值,但这是非常容易出错的,因为较大的 html 页面包含许多嵌套表格。我只想要最里面单元格的 InnerText。也许还有一个 LINQ 解决方案可以解决这个问题,那么我更喜欢那个。

更新 我注意到使用 LastOrDefault 而不是 FirstOrDefault 可能是一个可行的解决方法,因为它似乎返回匹配的最里面的单元格条件:

var invoiceCell = doc.DocumentNode.Descendants("td")
    .LastOrDefault(cell => cell.InnerText.Contains("Invoice-Number"));

最佳答案

这是另一种使用 XPath 来涵盖这两种情况的替代方案——当目标文本直接位于单元格内时,当目标文本包含在跨度中时:

var xpath = "//td[contains(text(),'Invoice-Number') or contains(span,'Invoice-Number')]";
var invoiceCell = doc.DocumentNode.SelectSingleNode(xpath);

关于c# - 仅获取此节点的 InnerText,不包括子节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33753943/

相关文章:

php - 使用 mb_substr() 管理韩语多字节字符串会产生乱码

c# - 如何将 float 作为小时相加,输出小时分秒

c# - Azure cloudapp.net 域和重复内容问题

javascript - 在 JavaScript 中单击时在图像周围创建边框?

python - 值错误: unsupported format character 'a' (0x61) at index 55 with URL string

java 字符串a中的字母包含在字符串b中

c# - 在 Quartz.NET 中获取触发器属性

c# - Entity Framework 6 关系

c# - 如何在代码隐藏中的转发器内部的 div 上设置类?

javascript - HTML 框格式