I have rewrote this XPath expression to linq, but something is wrong (no element found exception). My Html:
string xml = @"
<root>
<div id=""main"">
<div class=""content"">
<ul>
something
</ul>
</div>
<div class=""content"">
<ul>
something
</ul>
</div>
<div class=""content"">
<ul>
<li>
<div>My text</div>
</li>
</ul>
</div>
</div>
</root>
";
Xpath:
//div[@id="main"]//div[@class="content"]/ul/li/div
LINQ:
string Content =
doc.DocumentNode.Descendants("div").First(x => x.GetAttributeValue("id", null) == "main")
.Descendants("div").First(x => x.GetAttributeValue("class", null) == "content")
.Descendants("ul").First()
.Descendants("li").First()
.Descendants("div").First().InnerText
background: I have to use LINQ, because I am using Portable library.
I have already solved my problem with slightly different expression:
string Content =
doc.DocumentNode.Descendants("div").First(x => x.GetAttributeValue("id", null) == "main")
.Descendants("div").Where(x => x.GetAttributeValue("class", null) == "content").ElementAt(2)
.Descendants("ul").First()
.Descendants("li").First()
.Descendants("div").First().InnerText;
It works, but it is not same as Xpath.
So I am asking you: Does exist LINQ expression, which finds Node with InnerText without specifying exact location (like Xpath)?
I think this is what you want... you are expecting the first match in the document and not all matches right?
string Content =
doc.DocumentNode.Descendants("div").Where(x => x.GetAttributeValue("id", null) == "main")
.Descendants("div").Where(x => x.GetAttributeValue("class", null) == "content")
.Elements("ul")
.Elements("li")
.Elements("div").First().Value;
In general...
XPath '//' -> translates to LINQ .Descendants
XPath '/' -> translates to LINQ .Elements
This code will retrieve the InnerText of your target div:
var doc = new HtmlDocument();
string xml = @"<root>
<div id=""main"">
<div class=""content"">
<ul>
<li>
<div>Test</div>
</li>
<ul>
</div>
</div>
</root>";
var bytes = System.Text.Encoding.UTF8.GetBytes(xml);
var memStream = new MemoryStream(bytes);
doc.Load(memStream);
var innerText =
doc.DocumentNode.Descendants("div").Where(x => x.GetAttributeValue("id", null) == "main").First()
.Descendants("div").Where(x => x.GetAttributeValue("class", null) == "content").First()
.Elements("ul").First()
.Elements("li").First()
.Elements("div").First().InnerText;
When this is run "innerText" is equal to "Test" (ie the innerText of the div)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.