Получить значение атрибута с помощью XPath и HtmlAgilityPack - PullRequest
9 голосов
/ 29 декабря 2011

У меня есть HTML-документ, и я анализирую его с помощью XPath. Я хочу получить значение элемента input, но это не сработало.

Мой HTML:

<tbody>
  <tr>
    <td>
      <input type="text" name="item" value="10743" readonly="readonly" size="10"/>
    </td>
  </tr>
</tbody>

Мой код:

using HtmlAgilityPack;

HtmlAgilityPack.HtmlDocument doc; 
HtmlWeb hw = new HtmlWeb();
HtmlNodeCollection node = doc.DocumentNode.SelectNodes("//input/@value");
string s=node[0].InnerText;

Итак Я хочу получить значение: "10743" (и я не против получить еще один тег с ответом.)

Ответы [ 3 ]

14 голосов
/ 29 декабря 2011

Вы можете получить его в .Attributes коллекции:

var doc = new HtmlAgilityPack.HtmlDocument();
doc.Load("file.html");
var node = doc.DocumentNode.SelectNodes("//input") [0];
var val = node.Attributes["value"].Value; //10743
7 голосов
/ 14 марта 2013

Вы также можете напрямую получить атрибут, если используете HtmlNavigator.

//Load document from some html string
HtmlDocument hdoc = new HtmlDocument();
hdoc.LoadHtml(htmlContent);

//load navigator for current document
HtmlNavigator navigator = (HtmlNodeNavigator)hdoc.CreateNavigator();

//Get value with given xpath
string xpath = "//input/@value";
string val = navigator.SelectSingleNode(xpath).Value;
6 голосов
/ 29 декабря 2011

Обновление2 : Вот пример кода, как получить значения атрибутов с помощью Html Agility Pack:

http://htmlagilitypack.codeplex.com/wikipage?title=Examples

 HtmlDocument doc = new HtmlDocument();
 doc.Load("file.htm");
 foreach(HtmlNode link in doc.DocumentElement.SelectNodes("//a[@href"])
 {
    HtmlAttribute att = link.Attributes["href"];
    att.Value = FixLink(att);
 }
 doc.Save("file.htm");

Вы, очевидно,необходимо адаптировать этот код к вашим потребностям - например, вы не будете изменять атрибуты, а просто будете использовать att.Value.


Обновление : вы также можете посмотреть на этовопрос:

Выбор значений атрибутов с помощью html Agility Pack


Ваша проблема, скорее всего, связана с проблемой пространства имен по умолчанию - найдите «XPath default namespace c #», и вы найдете много хороших решений (подсказка: используйте перегрузку SelectNodes(), которая имеет XmlNamespaceManager аргумент).

Следующий код показывает, что можно получить для атрибута в документе в «без пространства имен»:

using System;
using System.IO;
using System.Xml;

public class Sample
{

    public static void Main()
    {

        XmlDocument doc = new XmlDocument();
        doc.LoadXml("<input value='novel' ISBN='1-861001-57-5'>" +
                    "<title>Pride And Prejudice</title>" +
                    "</input>");

        XmlNode root = doc.DocumentElement;

        XmlNode value = doc.SelectNodes("//input/@value")[0];

        Console.WriteLine("Inner text: " + value.InnerText);
        Console.WriteLine("InnerXml: " + value.InnerXml);
        Console.WriteLine("OuterXml: " + value.OuterXml);
        Console.WriteLine("Value: " + value.Value);

    }
}

Результат запуска этого приложения: :

Inner text: novel
InnerXml: novel
OuterXml: value="novel"
Value: novel

Теперь для документа, который находится в пространстве имен по умолчанию :

using System;
using System.IO;
using System.Xml;

public class Sample
{

    public static void Main()
    {

        XmlDocument doc = new XmlDocument();
        doc.LoadXml("<input xmlns='some:Namespace' value='novel' ISBN='1-861001-57-5'>" +
                    "<title>Pride And Prejudice</title>" +
                    "</input>");

        XmlNode root = doc.DocumentElement;

        XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
        nsmgr.AddNamespace("x", "some:Namespace");

        XmlNode value = doc.SelectNodes("//x:input/@value", nsmgr)[0];

        Console.WriteLine("Inner text: " + value.InnerText);
        Console.WriteLine("InnerXml: " + value.InnerXml);
        Console.WriteLine("OuterXml: " + value.OuterXml);
        Console.WriteLine("Value: " + value.Value);

    }
}

Запуск этого приложения снова приводит к желаемым результатам :

Inner text: novel
InnerXml: novel
OuterXml: value="novel"
Value: novel
...