Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Linq从XML/HTML提取元标记?_Xml_Linq_Meta Tags - Fatal编程技术网

如何使用Linq从XML/HTML提取元标记?

如何使用Linq从XML/HTML提取元标记?,xml,linq,meta-tags,Xml,Linq,Meta Tags,我试图解析HTML文件中的一些数据,但我的Linq语句不起作用。下面是XML/HTML。下面,我如何从geo.position元标记中提取字符串“41.8;12.23”?谢谢 这是我的林肯 String longLat = (String) from el in xdoc.Descendants() where (string)el.Name.LocalName == "meta" &a

我试图解析HTML文件中的一些数据,但我的Linq语句不起作用。下面是XML/HTML。下面,我如何从geo.position元标记中提取字符串“41.8;12.23”?谢谢

这是我的林肯

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

<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>

你的
html
标签周围有
span

您可以使用XLinq实现这一点,但它只支持格式良好的XML。你可能想看看这个

编辑-这对我很有用:

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();

我同意Thorarin-使用HTML敏捷包,它更加健壮

但是,我怀疑您在使用LinqToXML时遇到的问题是因为名称空间。有关如何在查询中处理它们的信息,请参见

“如果XML位于默认名称空间中,则仍必须声明XNamespace变量,并将其与本地名称组合,以生成用于查询的限定名称。”


查询XML树时最常见的问题之一是,如果XML树具有默认名称空间,开发人员有时编写查询时就好像XML不在名称空间中一样。”

我敢打赌,您遇到的问题来自于没有使用
XmlNamespaceManager
正确引用名称空间。以下是两种方法:

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);
stringxml=
@"
罗密菲米奇诺,意大利
";
字符串ns=”http://www.w3.org/1999/xhtml";
XmlNamespaceManager-nsm;
//林前:
XmlDocument d=新的XmlDocument();
d、 LoadXml(xml);
nsm=新的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—请注意,您必须创建一个XmlReader,以便
//在创建XmlNamespaceManager时使用其名称表:
XmlReader xr=XmlReader.Create(新的StringReader(xml));
XDocument xd=XDocument.Load(xr);
nsm=新的XmlNamespaceManager(xr.NameTable);
nsm.AddNamespace(“h”,ns);
控制台写入线(
xd.XPathSelectElement(“/span/h:html/h:head/h:meta[@name='geo.position']”,nsm)
.属性(“内容”)。价值);

在html下划线,然后单击“代码”按钮查看此页面以获取完整的标记参考。再加上不起作用的linq声明怎么样?非常感谢,Thorarin。我使用HTML敏捷包获得XDocument——该包添加了Span。这不是格式良好的XML吗?对解析器来说确实如此。是的,实际上是这样。我注意到缺少双引号,但没有注意到doctype实际上已转换为XML注释;)谢谢你,丹。是的,我是Agility Pack的忠实粉丝,它让我产生了这个问题我还有其他Linq查询,它们对同一个文档起作用。我添加了一个查询示例,但没有添加它为我提取的大表。
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);