HtmlAgilityPack SelectNodes表达式忽略具有特定属性的元素

时间:2012-11-05 03:07:38

标签: c# xpath html-agility-pack selectnodes

我正在尝试选择除脚本节点以外的节点和一个名为'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";
        }

2 个答案:

答案 0 :(得分: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)]"

答案 1 :(得分: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";
}