Pergunta

Estou tentando analisar um pouco de dados de um arquivo HTML, mas minha instrução LINQ não está funcionando. Aqui está o xml/html. Abaixo, como posso extrair a string "41.8; 12.23" da meta Geo.Position? THX!!

Aqui está o meu Linq

   String longLat = (String)
        from el in xdoc.Descendants()
              where
               (string)el.Name.LocalName == "meta"
               & el.FirstAttribute.Name == "geo.position"
                select (String) el.LastAttribute.Value;

Aqui está o meu xdocument

<span>
  <!--CTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dt -->
  <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <meta content="application/xhtml+xml; charset=utf-8" http-equiv="Content-Type" />
      <meta content="text/css" http-equiv="Content-Style-Type" />
      <meta name="geo.position" content="41.8;12.23" />
      <meta name="geo.placename" content="RomeFiumicino, Italy" />
      <title>RomeFiumicino, Italy</title>
    </head>
    <body />
  </html>
</span>

EDIT: Minha consulta como não dada retorna nada. A consulta "interna" parece retornar uma lista de todos os elementos de meta, em vez de apenas o único elemento que eu quero.

EDIT: A seguinte consulta Linq funciona contra o mesmo xdocument para retiver uma tabela com o nome da classe = "dados"

    var dataTable =
        from el in xdoc.Descendants()
        where (string)el.Attribute("class") == "data"
        select el;
Foi útil?

Solução

UMA span ao redor do seu html marcação?

Você poderia fazer isso com o XLINQ, mas ele só suportaria XML bem formado. Você pode querer olhar para o HTML Agility Pack em vez de.

Editar - Isso funciona para mim:

string xml = "...";
var geoPosition = XElement.Parse(xml).Descendants().
    Where(e => e.Name.LocalName == "meta" &&
        e.Attribute("name") != null &&
        e.Attribute("name").Value == "geo.position").
    Select(e => e.Attribute("content").Value).
    SingleOrDefault();

Outras dicas

Eu aposto que o problema que você está tendo vem de não referenciar o espaço de nome corretamente com um XmlNamespaceManager. Aqui estão duas maneiras de fazer isso:

string xml =
        @"<span>
   <!--CTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN""
        ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dt -->
   <html xmlns=""http://www.w3.org/1999/xhtml"">
    <head>
     <meta content=""application/xhtml+xml; charset=utf-8"" http-equiv=""Content-Type"" />
      <meta content=""text/css"" http-equiv=""Content-Style-Type"" />
      <meta name=""geo.position"" content=""41.8;12.23"" />
      <meta name=""geo.placename"" content=""RomeFiumicino, Italy"" />
      <title>RomeFiumicino, Italy</title>
    </head>
    <body />
   </html>
    </span>";

    string ns = "http://www.w3.org/1999/xhtml";
    XmlNamespaceManager nsm;

    // pre-Linq:
    XmlDocument d = new XmlDocument();
    d.LoadXml(xml);
    nsm = new XmlNamespaceManager(d.NameTable);
    nsm.AddNamespace("h", ns);

    Console.WriteLine(d.SelectSingleNode(
        "/span/h:html/h:head/h:meta[@name='geo.position']/@content", nsm).Value);

    // Linq - note that you have to create an XmlReader so that you can
    // use its NameTable in creating the XmlNamespaceManager:
    XmlReader xr = XmlReader.Create(new StringReader(xml));
    XDocument xd = XDocument.Load(xr);
    nsm = new XmlNamespaceManager(xr.NameTable);
    nsm.AddNamespace("h", ns);

    Console.WriteLine(
        xd.XPathSelectElement("/span/h:html/h:head/h:meta[@name='geo.position']", nsm)
            .Attribute("content").Value);

Eu concordo com o Thorarin - use o pacote de agilidade HTML, é muito mais robusto.

No entanto, suspeito que o problema que você esteja tendo usando Linqtoxml é por causa do espaço para nome. Ver Msdn aqui Para como lidar com eles em suas consultas.

"Se você possui XML que está em um espaço para nome padrão, ainda deve declarar uma variável xnamespace e combiná -la com o nome local para fazer um nome qualificado para ser usado na consulta.

Um dos problemas mais comuns ao consultar árvores XML é que, se a árvore XML tiver um espaço para nome padrão, o desenvolvedor às vezes escreve a consulta como se o XML não estivesse em um espaço para nome ".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top