HtmlAgilityPack 在 C# 中同时获取两个节点
HtmlAgilityPack get two nodes simultaneously in c#
我正在尝试解析 html 页面,
我将从这段代码中得到一对节点
<li class="classli">
<div class="element">element1</div>
<div class="description">description1</div>
</li>
<li class="classli">
<div class="element">element2</div>
<div class="description">description2</div>
</li>
<li class="classli">
<div class="xxxelementclass">element3</div>
<div class="description">description3</div>
</li>
<li class="classli">
<div class="element">element4</div>
<div class="xxxclass">description4</div>
</li>
我在 C# 中试过这个:
foreach(var node in doc.SelectNodes("//li[contains(@class,classli)]"))
{
listelement.add(node.SelectSingleNode("//div[contains(@class,element)]").InnerText);
listdescription(node.SelectSingleNode("//div[contains(@class,description)]").InnerText);
}
在HTML页面中,并不是所有的(li)标签都包含相同的子标签,我
只会在两者都存在的情况下获得描述和元素
使您的 xpath 中的每个看起来如下所示
//li[contains(@class,'classli') and ./div[contains(@class,'element')] and ./div[contains(@class,'description')]]
这将只考虑具有给定 类 的两个 div 的元素作为 child 节点,还要注意你的每个内部的 xpaths 需要开始寻找从开始的后代节点li 节点,所以你需要使用 ./
来表示 children 或 .//
来表示
等后代
./div[contains(@class,'element')]
./div[contains(@class,'description')]
CSS class 匹配的正确 XPath 表达式有点复杂。采用适度的方法,即 this other answer 中发布的第二个代码片段,您的任务的 XPath 如下(为了便于阅读,格式化为行):
var query = @"//li[contains(concat(' ', @class, ' '), ' classli ')]
[div[contains(concat(' ', @class, ' '), ' element ')]]
[div[contains(concat(' ', @class, ' '), ' description ')]]";
foreach(var node in doc.SelectNodes(query))
{
var elementQuery = "div[contains(concat(' ', @class, ' '), ' element ')]";
listelement.add(node.SelectSingleNode(elementQuery).InnerText);
var descriptionQuery = "div[contains(concat(' ', @class, ' '), ' description ')]";
listdescription.add(node.SelectSingleNode(descriptionQuery).InnerText);
}
AsEnumerable 谢谢大家的帮助
我是这样解决的
foreach(var node in doc.SelectNodes("//li[contains(@class,classli)]"))
{
List<HTMLNODE> Child = node.childnodes.where(o=> (o.getattribbutevalue(class,"") == "element") or (o.getattribbutevalue(class,"") == "description")).AsEnumerable().ToList();
}
For(int i = 0; i <= Child.count-1;i=i+2)
{
listelement.add(Child[i].InnerHtml;
listdescription.add(Child[i+1].InnerHtml;
}
我正在尝试解析 html 页面, 我将从这段代码中得到一对节点
<li class="classli">
<div class="element">element1</div>
<div class="description">description1</div>
</li>
<li class="classli">
<div class="element">element2</div>
<div class="description">description2</div>
</li>
<li class="classli">
<div class="xxxelementclass">element3</div>
<div class="description">description3</div>
</li>
<li class="classli">
<div class="element">element4</div>
<div class="xxxclass">description4</div>
</li>
我在 C# 中试过这个:
foreach(var node in doc.SelectNodes("//li[contains(@class,classli)]"))
{
listelement.add(node.SelectSingleNode("//div[contains(@class,element)]").InnerText);
listdescription(node.SelectSingleNode("//div[contains(@class,description)]").InnerText);
}
在HTML页面中,并不是所有的(li)标签都包含相同的子标签,我 只会在两者都存在的情况下获得描述和元素
使您的 xpath 中的每个看起来如下所示
//li[contains(@class,'classli') and ./div[contains(@class,'element')] and ./div[contains(@class,'description')]]
这将只考虑具有给定 类 的两个 div 的元素作为 child 节点,还要注意你的每个内部的 xpaths 需要开始寻找从开始的后代节点li 节点,所以你需要使用 ./
来表示 children 或 .//
来表示
./div[contains(@class,'element')]
./div[contains(@class,'description')]
CSS class 匹配的正确 XPath 表达式有点复杂。采用适度的方法,即 this other answer 中发布的第二个代码片段,您的任务的 XPath 如下(为了便于阅读,格式化为行):
var query = @"//li[contains(concat(' ', @class, ' '), ' classli ')]
[div[contains(concat(' ', @class, ' '), ' element ')]]
[div[contains(concat(' ', @class, ' '), ' description ')]]";
foreach(var node in doc.SelectNodes(query))
{
var elementQuery = "div[contains(concat(' ', @class, ' '), ' element ')]";
listelement.add(node.SelectSingleNode(elementQuery).InnerText);
var descriptionQuery = "div[contains(concat(' ', @class, ' '), ' description ')]";
listdescription.add(node.SelectSingleNode(descriptionQuery).InnerText);
}
AsEnumerable 谢谢大家的帮助 我是这样解决的
foreach(var node in doc.SelectNodes("//li[contains(@class,classli)]"))
{
List<HTMLNODE> Child = node.childnodes.where(o=> (o.getattribbutevalue(class,"") == "element") or (o.getattribbutevalue(class,"") == "description")).AsEnumerable().ToList();
}
For(int i = 0; i <= Child.count-1;i=i+2)
{
listelement.add(Child[i].InnerHtml;
listdescription.add(Child[i+1].InnerHtml;
}