0

我已将此 XPath 表达式重写为 linq,但出现了问题(未找到元素异常)。我的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

林克:

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

背景:我必须使用 LINQ,因为我使用的是便携式库。

我已经用稍微不同的表达方式解决了我的问题:

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;

它可以工作,但它与 Xpath 不同。

所以我问你:是否存在 LINQ 表达式,它在没有指定确切位置的情况下找到带有 InnerText 的节点(如 Xpath)?

4

2 回答 2

0

此代码将检索目标 div 的 InnerText:

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;

运行时“innerText”等于“Test”(即 div 的 innerText)

于 2013-10-30T00:30:06.133 回答
0

我认为这就是您想要的...您期望文档中的第一个匹配项,而不是所有匹配项,对吗?

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;

一般来说...

XPath '//' -> 转换为 LINQ .Descendants

XPath '/' -> 转换为 LINQ .Elements

于 2013-10-30T00:11:52.260 回答