6

我正在尝试选择除脚本节点和具有名为“relativeNav”的类的 ul 之外的节点。有人可以指导我走向正确的道路吗?我一直在寻找一个星期,但我无法在任何地方找到它。目前我有这个,但它显然也选择了 //ul[@class='relativeNav'] 。无论如何要放置一个 NOT 表达式,以便 SelectNode 会忽略那个?

        foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//body//*[not(self::script)]/text()"))
        {
            Console.WriteLine("Node: " + node);
            singleString += node.InnerText.Trim() + "\n";
        }
4

2 回答 2

4

给定一个 Html 文档,其结构类似于:

<html>
<head><title>HtmlDocument</title>
</head>
<body>
<div>
<span>Hello Span World</span>
<script>
Script Text
</script>
</div>
<ul class='relativeNav'>
<li>Hello </li>
<li>Li</li>
<li>World</li>
</ul>
</body>
</html>

以下 XPath 表达式将选择所有不是脚本元素的节点,不包括具有类“relativeNav”的 UL 元素的所有子元素:

var nodes = htmlDoc.DocumentNode.SelectNodes("//body//*[not(parent::ul[@class='relativeNav']) and not(self::script)]/text()");

更新:忘了提到,如果您需要排除 ul[class='relativeNav'] 的任何孩子,而不管它们的深度如何,您应该使用:

"//body//*[not(ancestor::ul[@class='relativeNav']) and not(self::script)]/text()"

如果您还想排除 ul 元素(在上面的示例中有些不相关,因为该元素不包含文本),您应该指定:

"//body//*[not(ancestor-or-self::ul[@class='relativeNav']) and not(self::script)]"
于 2012-11-05T07:59:09.867 回答
2

我希望这是你需要的:

HtmlDocument doc = new HtmlDocument();
var nodesToExclude1 = doc.DocumentNode.SelectNodes("//ul[@class='relativeNav']");
var nodesToExclude2 = doc.DocumentNode.SelectNodes("//body//script");
var requiredNodes = doc.DocumentNode.SelectNodes("//")
                       .Where(node => !nodesToExclude1.Contains(node) &&
                                      !nodesToExclude2.Contains(node));

foreach (HtmlNode node in requiredNodes)
{
    Console.WriteLine("Node: " + node);
    singleString += node.InnerText.Trim() + "\n";
}
于 2012-11-05T03:30:23.277 回答