Selezione del valore dell'attributo utilizzando XPath e HtmlAgilityPack

c# html html-agility-pack xml xpath

Domanda

Sto cercando di ottenere il secondo valore di attributo di un meta tag usando un'espressione xpath nel pacchetto di agilità html: Il meta tag:

<meta name="pubdate" content="2012-08-30" />

L'espressione del percorso xml sto usando:

//meta[@name='pubdate']/@content

Ma non restituisce nulla. Ho provato a cercare e implementare questa soluzione:

//meta[@name='pubdate']/string(@content)

Un altro modo:

string(//meta[@name='pubdate']/@content)

Ma dà l'eccezione xml nel pacchetto di agilità html. Un'altra soluzione non ha funzionato altrettanto bene.

//meta[@name='pubdate']/data(@content)

Per ragioni ho voluto utilizzare solo il percorso xml (e non le funzioni del pacchetto agility html per ottenere il valore dell'attributo). La funzione che uso è qui sotto:

date = TextfromOneNode(document.DocumentNode.SelectSingleNode(".//body"), "meta[@name='pubdate']/@content");
public static string TextfromOneNode(HtmlNode node, string xmlPath)
{
    string toReturn = "";
    if(node.SelectSingleNode(xmlPath) != null)
    {
        toReturn = node.SelectSingleNode(xmlPath).InnerText;
    }
    return toReturn;
}

Finora sembra che non ci sia modo di usare l'espressione del percorso xml per ottenere direttamente un valore di attributo. Qualche idea?

Risposta accettata

C'è un modo con HtmlNodeNavigator :

public static string TextfromOneNode(HtmlNode node, string xmlPath)
{
    string toReturn = "";
    var navigator = (HtmlAgilityPack.HtmlNodeNavigator)node.CreateNavigator();
    var result = navigator.SelectSingleNode(xmlPath);
    if(result != null)
    {
        toReturn = result.Value;
    }
    return toReturn;
}

Il seguente esempio di app per console dimostra come HtmlNodeNavigator.SelectSingleNode() con XPath che restituisce l'elemento e XPath che restituisce l'attributo:

var raw = @"<div>
<meta name='pubdate' content='2012-08-30' />
<span>foo</span>
</div>";
var doc = new HtmlAgilityPack.HtmlDocument(); 
doc.LoadHtml(raw);

var navigator = (HtmlAgilityPack.HtmlNodeNavigator)doc.CreateNavigator();

var xpath1 = "//meta[@name='pubdate']/@content";
var xpath2 = "//span";

var result = navigator.SelectSingleNode(xpath1);
Console.WriteLine(result.Value);
result = navigator.SelectSingleNode(xpath2);
Console.WriteLine(result.Value);

demo dotnetfiddle

produzione :

2012-08-30
foo

Risposta popolare

Utilizzando xml linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = "<meta name=\"pubdate\" content=\"2012-08-30\" />";
            XElement meta = XElement.Parse(input);
            DateTime output = (DateTime)meta.Attribute("content");
        }
    }
}


Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché