У меня есть следующий код HTML, который я бы хотел проанализировать:
<h3 class='bar'>
<a href='http://anysite.com/index.php?showuser=7195' title='Profile view'>THIS_IS_USERNAME</a>
<a href='http://anysite.com/index.php?showuser=7195&f=' class='__user __id7195' title='Profile view'>
<img src='http://anysite.com/public/style_images/car/user_popup.png' alt='' />
</a>
</h3>
Здесь мне нужно выбрать имя пользователя («THIS_IS_USERNAME») и ссылку на профиль (« http://anysite.com/index.php?showuser=7195 »)
Я могу выбрать верхний узел h3, используя следующий код:
List<HtmlNode> resultSearch = HTMLPage.DocumentNode.Descendants()
.Where(
x => x.Name.Equals("h3")
&& x.Attributes["class"] != null
&& x.Attributes["class"].Value.Equals("bar")
)
.ToList();
Но как я могу получить не сам узел «h3», а «а» внутри «h3» с этой ссылкой атрибутов, которая содержит имя пользователя и ссылку на профиль, который мне нужен?
Вы можете напрямую запросить узел ссылки, он довольно отличается от атрибута Title на нем.
В этом случае использование XPath, вероятно, проще, поскольку оно обрабатывает все промежуточные проверки на нуль, и оно просто безопасно для типов, так как ваш запрос Linq будет содержать много постоянных строк:
var node = HTMLPage.DocumentNode.SelectSingleNode("//hr[@class='Bar']/a[@title='Profile View' and @href");
if (node != null)
{
string link = node.Attributes["href"].Value;
string username = node.InnerText;
}
Вы можете написать аналогичный код с помощью синтаксиса Linq, он сначала ищет тег ссылки, а затем обратный путь, чтобы найти родительский элемент h3 для него. Таким образом, вам не нужно проверять промежуточные нули;):
var node = HtmlPage.DocumentNode.Descendants("a")
.Where(a =>
a.Ascendants("h3")
.Any(h3 =>
h3.Attributes["class"] != null
&& a.Attributes["class"].Value == "bar"
)
)
.Where(a =>
a.Attributes["title"] != null
&& a.Attributes["title"].Value == "Profile View"
&& a.Attributes["href"] != null
)
.FirstOrDefault();
if (node != null)
{
string link = node.Attributes["href"].value;
string username = node.InnerText;
}
Или вы можете использовать его положение как первый <a>
дочерний <a>
"bar":
// the call to First() will throw an exception if the h3 isn't found.
// returning an empty HtmlNode will allow you to ignore that
var node = (HtmlPage.DocumentNode.Descendants("h3")
.FirstOrDefault( h =>
h3.Attributes["class"] != null
&& a.Attributes["class"].Value == "bar")
) ?? HtmlPage.CreateElement("h3"))
.Elements("a").FirstOrDefault();
if (node != null)
{
string link = node.Attributes["href"].value;
string username = node.InnerText;
}